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