Mercurial > libervia-backend
annotate src/plugins/plugin_misc_imap.py @ 636:7ea6d5a86e58
plugin XEP-0085: Chat State Notifications
- new "options" parameter to send chat states
- plugin command export: messages without body are now delivered (since all the chat states other than "active" need them)
author | souliane <souliane@mailoo.org> |
---|---|
date | Thu, 05 Sep 2013 20:48:47 +0200 |
parents | 84a6e83157c2 |
children | 4f747d7fde8c |
rev | line source |
---|---|
253 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
4 # SàT plugin for managing imap server |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
5 # Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) |
253 | 6 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
10 # (at your option) any later version. |
253 | 11 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
15 # GNU Affero General Public License for more details. |
253 | 16 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
594
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
253 | 19 |
20 from logging import debug, info, error | |
21 import warnings | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
22 from twisted.internet import protocol, defer |
253 | 23 from twisted.words.protocols.jabber import error as jab_error |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
24 from twisted.cred import portal, checkers, credentials |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
25 from twisted.cred import error as cred_error |
253 | 26 from twisted.mail import imap4 |
260
c8406fe5e81e
Added SMTP server plugin, for sending messages from classic MUA \o/
Goffi <goffi@goffi.org>
parents:
257
diff
changeset
|
27 from twisted.python import failure |
253 | 28 from email.parser import Parser |
29 import email.message | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
30 import os |
253 | 31 from cStringIO import StringIO |
32 from twisted.internet import reactor | |
33 import pdb | |
34 | |
35 from zope.interface import implements | |
36 | |
37 PLUGIN_INFO = { | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
38 "name": "IMAP server Plugin", |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
39 "import_name": "IMAP", |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
40 "type": "Misc", |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
41 "protocols": [], |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
42 "dependencies": ["Maildir"], |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
43 "main": "IMAP_server", |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
44 "handler": "no", |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
45 "description": _("""Create an Imap server that you can use to read your "normal" type messages""") |
253 | 46 } |
47 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
48 |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
49 class IMAP_server(object): |
439
866dbb0d7d87
plugin maildir: maildir now use PersistentBinaryDictionary to store profile specific data
Goffi <goffi@goffi.org>
parents:
412
diff
changeset
|
50 #TODO: connect profile on mailbox request, once password is accepted |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
51 |
253 | 52 params = """ |
53 <params> | |
54 <general> | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
55 <category name="Mail Server"> |
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
56 <param name="IMAP Port" value="10143" type="string" /> |
253 | 57 </category> |
58 </general> | |
59 </params> | |
60 """ | |
61 | |
62 def __init__(self, host): | |
63 info(_("Plugin Imap Server initialization")) | |
64 self.host = host | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
65 |
253 | 66 #parameters |
67 host.memory.importParams(self.params) | |
68 | |
261
0ecd9c33fa3a
IMAP & SMTP Port parameters are now merged in "Mail Server" category
Goffi <goffi@goffi.org>
parents:
260
diff
changeset
|
69 port = int(self.host.memory.getParamA("IMAP Port", "Mail Server")) |
253 | 70 info(_("Launching IMAP server on port %d"), port) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
71 |
253 | 72 self.server_factory = ImapServerFactory(self.host) |
73 reactor.listenTCP(port, self.server_factory) | |
74 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
75 |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
76 class Message(object): |
253 | 77 implements(imap4.IMessage) |
78 | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
79 def __init__(self, uid, flags, mess_fp): |
253 | 80 debug('Message Init') |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
81 self.uid = uid |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
82 self.flags = flags |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
83 self.mess_fp = mess_fp |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
84 self.message = Parser().parse(mess_fp) |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
85 |
253 | 86 def getUID(self): |
87 """Retrieve the unique identifier associated with this message. | |
88 """ | |
89 debug('getUID (message)') | |
90 return self.uid | |
91 | |
92 def getFlags(self): | |
93 """Retrieve the flags associated with this message. | |
94 @return: The flags, represented as strings. | |
95 """ | |
96 debug('getFlags') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
97 return self.flags |
253 | 98 |
99 def getInternalDate(self): | |
100 """Retrieve the date internally associated with this message. | |
101 @return: An RFC822-formatted date string. | |
102 """ | |
103 debug('getInternalDate') | |
104 return self.message['Date'] | |
105 | |
106 def getHeaders(self, negate, *names): | |
107 """Retrieve a group of message headers. | |
108 @param names: The names of the headers to retrieve or omit. | |
109 @param negate: If True, indicates that the headers listed in names | |
110 should be omitted from the return value, rather than included. | |
111 @return: A mapping of header field names to header field values | |
112 """ | |
113 debug('getHeaders %s - %s' % (negate, names)) | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
114 final_dict = {} |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
115 to_check = [name.lower() for name in names] |
253 | 116 for header in self.message.keys(): |
117 if (negate and not header.lower() in to_check) or \ | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
118 (not negate and header.lower() in to_check): |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
119 final_dict[header] = self.message[header] |
253 | 120 return final_dict |
121 | |
122 def getBodyFile(self): | |
123 """Retrieve a file object containing only the body of this message. | |
124 """ | |
125 debug('getBodyFile') | |
126 return StringIO(self.message.get_payload()) | |
127 | |
128 def getSize(self): | |
129 """Retrieve the total size, in octets, of this message. | |
130 """ | |
131 debug('getSize') | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
132 self.mess_fp.seek(0, os.SEEK_END) |
253 | 133 return self.mess_fp.tell() |
134 | |
135 def isMultipart(self): | |
136 """Indicate whether this message has subparts. | |
137 """ | |
138 debug('isMultipart') | |
139 return False | |
140 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
141 def getSubPart(self, part): |
253 | 142 """Retrieve a MIME sub-message |
143 @param part: The number of the part to retrieve, indexed from 0. | |
144 @return: The specified sub-part. | |
145 """ | |
146 debug('getSubPart') | |
147 return TypeError | |
148 | |
149 | |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
150 class SatMailbox(object): |
253 | 151 implements(imap4.IMailbox) |
152 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
153 def __init__(self, host, name, profile): |
253 | 154 self.host = host |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
155 self.listeners = set() |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
156 debug('Mailbox init (%s)', name) |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
157 if name != "INBOX": |
253 | 158 raise imap4.MailboxException("Only INBOX is managed for the moment") |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
159 self.mailbox = self.host.plugins["Maildir"].accessMessageBox(name, self.newMessage, profile) |
253 | 160 |
161 def newMessage(self): | |
162 """Called when a new message is in the mailbox""" | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
163 debug("newMessage signal received") |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
164 nb_messages = self.getMessageCount() |
253 | 165 for listener in self.listeners: |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
166 listener.newMessages(nb_messages, None) |
253 | 167 |
168 def getUIDValidity(self): | |
169 """Return the unique validity identifier for this mailbox. | |
170 """ | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
171 debug('getUIDValidity') |
253 | 172 return 0 |
173 | |
174 def getUIDNext(self): | |
175 """Return the likely UID for the next message added to this mailbox. | |
176 """ | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
177 debug('getUIDNext') |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
178 return self.mailbox.getNextUid() |
253 | 179 |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
180 def getUID(self, message): |
253 | 181 """Return the UID of a message in the mailbox |
182 @param message: The message sequence number | |
183 @return: The UID of the message. | |
184 """ | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
185 debug('getUID (%i)' % message) |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
186 #return self.mailbox.getUid(message-1) #XXX: it seems that this method get uid and not message sequence number |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
187 return message |
253 | 188 |
189 def getMessageCount(self): | |
190 """Return the number of messages in this mailbox. | |
191 """ | |
192 debug('getMessageCount') | |
193 ret = self.mailbox.getMessageCount() | |
194 debug("count = %i" % ret) | |
195 return ret | |
196 | |
197 def getRecentCount(self): | |
198 """Return the number of messages with the 'Recent' flag. | |
199 """ | |
200 debug('getRecentCount') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
201 return len(self.mailbox.getMessageIdsWithFlag('\\Recent')) |
253 | 202 |
203 def getUnseenCount(self): | |
204 """Return the number of messages with the 'Unseen' flag. | |
205 """ | |
206 debug('getUnseenCount') | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
207 return self.getMessageCount() - len(self.mailbox.getMessageIdsWithFlag('\\SEEN')) |
253 | 208 |
209 def isWriteable(self): | |
210 """Get the read/write status of the mailbox. | |
211 @return: A true value if write permission is allowed, a false value otherwise. | |
212 """ | |
213 debug('isWriteable') | |
214 return True | |
215 | |
216 def destroy(self): | |
217 """Called before this mailbox is deleted, permanently. | |
218 """ | |
219 debug('destroy') | |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
220 |
253 | 221 def requestStatus(self, names): |
222 """Return status information about this mailbox. | |
223 @param names: The status names to return information regarding. | |
224 The possible values for each name are: MESSAGES, RECENT, UIDNEXT, | |
225 UIDVALIDITY, UNSEEN. | |
226 @return: A dictionary containing status information about the | |
227 requested names is returned. If the process of looking this | |
228 information up would be costly, a deferred whose callback will | |
229 eventually be passed this dictionary is returned instead. | |
230 """ | |
231 debug('requestStatus') | |
232 return imap4.statusRequestHelper(self, names) | |
233 | |
234 def addListener(self, listener): | |
235 """Add a mailbox change listener | |
236 | |
237 @type listener: Any object which implements C{IMailboxListener} | |
238 @param listener: An object to add to the set of those which will | |
239 be notified when the contents of this mailbox change. | |
240 """ | |
241 debug('addListener %s' % listener) | |
242 self.listeners.add(listener) | |
243 | |
244 def removeListener(self, listener): | |
245 """Remove a mailbox change listener | |
246 | |
247 @type listener: Any object previously added to and not removed from | |
248 this mailbox as a listener. | |
249 @param listener: The object to remove from the set of listeners. | |
250 | |
251 @raise ValueError: Raised when the given object is not a listener for | |
252 this mailbox. | |
253 """ | |
254 debug('removeListener') | |
255 if listener in self.listeners: | |
256 self.listeners.remove(listener) | |
257 else: | |
258 raise imap4.MailboxException('Trying to remove an unknown listener') | |
259 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
260 def addMessage(self, message, flags=(), date=None): |
253 | 261 """Add the given message to this mailbox. |
262 @param message: The RFC822 formatted message | |
263 @param flags: The flags to associate with this message | |
264 @param date: If specified, the date to associate with this | |
265 @return: A deferred whose callback is invoked with the message | |
266 id if the message is added successfully and whose errback is | |
267 invoked otherwise. | |
268 """ | |
269 debug('addMessage') | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
270 raise imap4.MailboxException("Client message addition not implemented yet") |
253 | 271 |
272 def expunge(self): | |
273 """Remove all messages flagged \\Deleted. | |
274 @return: The list of message sequence numbers which were deleted, | |
275 or a Deferred whose callback will be invoked with such a list. | |
276 """ | |
277 debug('expunge') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
278 self.mailbox.removeDeleted() |
253 | 279 |
280 def fetch(self, messages, uid): | |
281 """Retrieve one or more messages. | |
282 @param messages: The identifiers of messages to retrieve information | |
283 about | |
284 @param uid: If true, the IDs specified in the query are UIDs; | |
285 """ | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
286 debug('fetch (%s, %s)' % (messages, uid)) |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
287 if uid: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
288 messages.last = self.mailbox.getMaxUid() |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
289 messages.getnext = self.mailbox.getNextExistingUid |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
290 for mess_uid in messages: |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
291 if mess_uid is None: |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
292 debug('stopping iteration') |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
293 raise StopIteration |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
294 try: |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
295 yield (mess_uid, Message(mess_uid, self.mailbox.getFlagsUid(mess_uid), self.mailbox.getMessageUid(mess_uid))) |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
296 except IndexError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
297 continue |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
298 else: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
299 messages.last = self.getMessageCount() |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
300 for mess_idx in messages: |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
301 if mess_idx > self.getMessageCount(): |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
302 raise StopIteration |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
303 yield (mess_idx, Message(mess_idx, self.mailbox.getFlags(mess_idx), self.mailbox.getMessage(mess_idx - 1))) |
253 | 304 |
305 def store(self, messages, flags, mode, uid): | |
306 """Set the flags of one or more messages. | |
307 @param messages: The identifiers of the messages to set the flags of. | |
308 @param flags: The flags to set, unset, or add. | |
309 @param mode: If mode is -1, these flags should be removed from the | |
310 specified messages. If mode is 1, these flags should be added to | |
311 the specified messages. If mode is 0, all existing flags should be | |
312 cleared and these flags should be added. | |
313 @param uid: If true, the IDs specified in the query are UIDs; | |
314 otherwise they are message sequence IDs. | |
315 @return: A dict mapping message sequence numbers to sequences of str | |
316 representing the flags set on the message after this operation has | |
317 been performed, or a Deferred whose callback will be invoked with | |
318 such a dict. | |
319 """ | |
320 debug('store') | |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
321 |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
322 flags = [flag.upper() for flag in flags] |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
323 |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
324 def updateFlags(getF, setF): |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
325 ret = {} |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
326 for mess_id in messages: |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
327 if (uid and mess_id is None) or (not uid and mess_id > self.getMessageCount()): |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
328 break |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
329 _flags = set(getF(mess_id) if mode else []) |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
330 if mode == -1: |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
331 _flags.difference_update(set(flags)) |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
332 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
333 _flags.update(set(flags)) |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
334 new_flags = list(_flags) |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
335 setF(mess_id, new_flags) |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
336 ret[mess_id] = tuple(new_flags) |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
337 return ret |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
338 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
339 if uid: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
340 messages.last = self.mailbox.getMaxUid() |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
341 messages.getnext = self.mailbox.getNextExistingUid |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
342 ret = updateFlags(self.mailbox.getFlagsUid, self.mailbox.setFlagsUid) |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
343 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
344 listener.flagsChanged(ret) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
345 return ret |
587
952322b1d490
Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
574
diff
changeset
|
346 |
255
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
347 else: |
55b750017b71
plugin IMAP, plugin Maildir: added flag, IMAP's uid management
Goffi <goffi@goffi.org>
parents:
254
diff
changeset
|
348 messages.last = self.getMessageCount() |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
349 ret = updateFlags(self.mailbox.getFlags, self.mailbox.setFlags) |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
350 newFlags = {} |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
351 for idx in ret: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
352 #we have to convert idx to uid for the listeners |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
353 newFlags[self.mailbox.getUid(idx)] = ret[idx] |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
354 for listener in self.listeners: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
355 listener.flagsChanged(newFlags) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
356 return ret |
253 | 357 |
358 def getFlags(self): | |
359 """Return the flags defined in this mailbox | |
360 Flags with the \\ prefix are reserved for use as system flags. | |
361 @return: A list of the flags that can be set on messages in this mailbox. | |
362 """ | |
363 debug('getFlags') | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
364 return ['\\SEEN', '\\ANSWERED', '\\FLAGGED', '\\DELETED', '\\DRAFT'] # TODO: add '\\RECENT' |
253 | 365 |
366 def getHierarchicalDelimiter(self): | |
367 """Get the character which delimits namespaces for in this mailbox. | |
368 """ | |
369 debug('getHierarchicalDelimiter') | |
370 return '.' | |
371 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
372 |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
373 class ImapSatAccount(imap4.MemoryAccount): |
253 | 374 #implements(imap4.IAccount) |
375 | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
376 def __init__(self, host, profile): |
253 | 377 debug("ImapAccount init") |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
378 self.host = host |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
379 self.profile = profile |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
380 imap4.MemoryAccount.__init__(self, profile) |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
381 self.addMailbox("Inbox") # We only manage Inbox for the moment |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
382 debug('INBOX added') |
253 | 383 |
384 def _emptyMailbox(self, name, id): | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
385 return SatMailbox(self.host, name, self.profile) |
253 | 386 |
387 | |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
388 class ImapRealm(object): |
253 | 389 implements(portal.IRealm) |
390 | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
391 def __init__(self, host): |
253 | 392 self.host = host |
393 | |
394 def requestAvatar(self, avatarID, mind, *interfaces): | |
395 debug('requestAvatar') | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
396 profile = avatarID.decode('utf-8') |
253 | 397 if imap4.IAccount not in interfaces: |
398 raise NotImplementedError | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
399 return imap4.IAccount, ImapSatAccount(self.host, profile), lambda: None |
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
400 |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
401 |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
587
diff
changeset
|
402 class SatProfileCredentialChecker(object): |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
403 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
404 This credential checker check against SàT's profile and associated jabber's password |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
405 Check if the profile exists, and if the password is OK |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
406 Return the profile as avatarId |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
407 """ |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
408 implements(checkers.ICredentialsChecker) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
409 credentialInterfaces = (credentials.IUsernamePassword, |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
410 credentials.IUsernameHashedPassword) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
411 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
412 def __init__(self, host): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
413 self.host = host |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
414 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
415 def _cbPasswordMatch(self, matched, profile): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
416 if matched: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
417 return profile.encode('utf-8') |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
418 else: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
419 return failure.Failure(cred_error.UnauthorizedLogin()) |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
420 |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
421 def requestAvatarId(self, credentials): |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
422 profiles = self.host.memory.getProfilesList() |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
423 if not credentials.username in profiles: |
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
424 return defer.fail(cred_error.UnauthorizedLogin()) |
574
89f9a50ce7bf
core, plugin imap, plugin smtp: fixed SMTP/IMAP integration. /!\ Profile need to be connected for IMAP server to work (will change in the future)
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
425 d = self.host.memory.asyncGetParamA("Password", "Connection", profile_key=credentials.username) |
89f9a50ce7bf
core, plugin imap, plugin smtp: fixed SMTP/IMAP integration. /!\ Profile need to be connected for IMAP server to work (will change in the future)
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
426 d.addCallback(lambda password: credentials.checkPassword(password)) |
89f9a50ce7bf
core, plugin imap, plugin smtp: fixed SMTP/IMAP integration. /!\ Profile need to be connected for IMAP server to work (will change in the future)
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
427 d.addCallback(self._cbPasswordMatch, credentials.username) |
89f9a50ce7bf
core, plugin imap, plugin smtp: fixed SMTP/IMAP integration. /!\ Profile need to be connected for IMAP server to work (will change in the future)
Goffi <goffi@goffi.org>
parents:
480
diff
changeset
|
428 return d |
253 | 429 |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
430 |
253 | 431 class ImapServerFactory(protocol.ServerFactory): |
432 protocol = imap4.IMAP4Server | |
433 | |
434 def __init__(self, host): | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
435 self.host = host |
253 | 436 |
437 def startedConnecting(self, connector): | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
438 debug(_("IMAP server connection started")) |
253 | 439 |
440 def clientConnectionLost(self, connector, reason): | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
441 debug(_("IMAP server connection lost (reason: %s)"), reason) |
253 | 442 |
443 def buildProtocol(self, addr): | |
594
e629371a28d3
Fix pep8 support in src/plugins.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
444 debug("Building protocol") |
253 | 445 prot = protocol.ServerFactory.buildProtocol(self, addr) |
446 prot.portal = portal.Portal(ImapRealm(self.host)) | |
257
012c38b56cdd
plugin IMAP, plugin Maildir: profile management
Goffi <goffi@goffi.org>
parents:
255
diff
changeset
|
447 prot.portal.registerChecker(SatProfileCredentialChecker(self.host)) |
253 | 448 return prot |