Mercurial > libervia-backend
comparison sat/plugins/plugin_misc_maildir.py @ 3028:ab2696e34d29
Python 3 port:
/!\ this is a huge commit
/!\ starting from this commit, SàT is needs Python 3.6+
/!\ SàT maybe be instable or some feature may not work anymore, this will improve with time
This patch port backend, bridge and frontends to Python 3.
Roughly this has been done this way:
- 2to3 tools has been applied (with python 3.7)
- all references to python2 have been replaced with python3 (notably shebangs)
- fixed files not handled by 2to3 (notably the shell script)
- several manual fixes
- fixed issues reported by Python 3 that where not handled in Python 2
- replaced "async" with "async_" when needed (it's a reserved word from Python 3.7)
- replaced zope's "implements" with @implementer decorator
- temporary hack to handle data pickled in database, as str or bytes may be returned,
to be checked later
- fixed hash comparison for password
- removed some code which is not needed anymore with Python 3
- deactivated some code which needs to be checked (notably certificate validation)
- tested with jp, fixed reported issues until some basic commands worked
- ported Primitivus (after porting dependencies like urwid satext)
- more manual fixes
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Aug 2019 19:08:41 +0200 |
parents | 26edcf3a30eb |
children |
comparison
equal
deleted
inserted
replaced
3027:ff5bcb12ae60 | 3028:ab2696e34d29 |
---|---|
1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python3 |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 | 3 |
4 # SàT plugin for managing Maildir type mail boxes | 4 # SàT plugin for managing Maildir type mail boxes |
5 # Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) | 5 # Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) |
6 | 6 |
137 """Remove a reference to a box | 137 """Remove a reference to a box |
138 @param name: name of the box | 138 @param name: name of the box |
139 @param mailboxUser: MailboxUser instance""" | 139 @param mailboxUser: MailboxUser instance""" |
140 if boxname not in self.__mailboxes: | 140 if boxname not in self.__mailboxes: |
141 err_msg = _("Trying to remove an mailboxUser not referenced") | 141 err_msg = _("Trying to remove an mailboxUser not referenced") |
142 log.error(_(u"INTERNAL ERROR: ") + err_msg) | 142 log.error(_("INTERNAL ERROR: ") + err_msg) |
143 raise MaildirError(err_msg) | 143 raise MaildirError(err_msg) |
144 assert self.__mailboxes[profile][boxname] == mailboxUser | 144 assert self.__mailboxes[profile][boxname] == mailboxUser |
145 del self.__mailboxes[profile][boxname] | 145 del self.__mailboxes[profile][boxname] |
146 | 146 |
147 def _checkBoxReference(self, boxname, profile): | 147 def _checkBoxReference(self, boxname, profile): |
156 """Return the date of a box""" | 156 """Return the date of a box""" |
157 try: | 157 try: |
158 return self.data[profile][boxname] # the boxname MUST exist in the data | 158 return self.data[profile][boxname] # the boxname MUST exist in the data |
159 except KeyError: | 159 except KeyError: |
160 err_msg = _("Boxname doesn't exist in internal data") | 160 err_msg = _("Boxname doesn't exist in internal data") |
161 log.error(_(u"INTERNAL ERROR: ") + err_msg) | 161 log.error(_("INTERNAL ERROR: ") + err_msg) |
162 raise MaildirError(err_msg) | 162 raise MaildirError(err_msg) |
163 | 163 |
164 def getUid(self, boxname, message_id, profile): | 164 def getUid(self, boxname, message_id, profile): |
165 """Return an unique integer, always ascending, for a message | 165 """Return an unique integer, always ascending, for a message |
166 This is mainly needed for the IMAP protocol | 166 This is mainly needed for the IMAP protocol |
209 """Return the message unique id from it's integer UID | 209 """Return the message unique id from it's integer UID |
210 @param boxname: name of the box where the message is | 210 @param boxname: name of the box where the message is |
211 @param message_uid: unique integer identifier | 211 @param message_uid: unique integer identifier |
212 @return: unique id of the message as given by MaildirMailbox or None if not found""" | 212 @return: unique id of the message as given by MaildirMailbox or None if not found""" |
213 box_data = self.__getBoxData(boxname, profile) | 213 box_data = self.__getBoxData(boxname, profile) |
214 for message_id in box_data.keys(): # TODO: this is highly inefficient on big mailbox, must be replaced in the future | 214 for message_id in list(box_data.keys()): # TODO: this is highly inefficient on big mailbox, must be replaced in the future |
215 if message_id == 'cur_idx': | 215 if message_id == 'cur_idx': |
216 continue | 216 continue |
217 if box_data[message_id][0] == message_uid: | 217 if box_data[message_id][0] == message_uid: |
218 return message_id | 218 return message_id |
219 return None | 219 return None |
246 """Return ids of messages where a flag is set | 246 """Return ids of messages where a flag is set |
247 @param boxname: name of the box where the message is | 247 @param boxname: name of the box where the message is |
248 @param flag: flag to check | 248 @param flag: flag to check |
249 @return: list of id (as given by MaildirMailbox)""" | 249 @return: list of id (as given by MaildirMailbox)""" |
250 box_data = self.__getBoxData(boxname, profile) | 250 box_data = self.__getBoxData(boxname, profile) |
251 assert(isinstance(flag, basestring)) | 251 assert(isinstance(flag, str)) |
252 flag = flag.upper() | 252 flag = flag.upper() |
253 result = [] | 253 result = [] |
254 for key in box_data: | 254 for key in box_data: |
255 if key == 'cur_idx': | 255 if key == 'cur_idx': |
256 continue | 256 continue |
294 """Remove an observer of maildir box changes | 294 """Remove an observer of maildir box changes |
295 @param callback: method to remove from obervers | 295 @param callback: method to remove from obervers |
296 @param boxname: name of the box which was observed | 296 @param boxname: name of the box which was observed |
297 @param signal: which signal was observed by the caller""" | 297 @param signal: which signal was observed by the caller""" |
298 if (profile, boxname) not in self.__observed: | 298 if (profile, boxname) not in self.__observed: |
299 err_msg = _(u"Trying to remove an observer for an inexistant mailbox") | 299 err_msg = _("Trying to remove an observer for an inexistant mailbox") |
300 log.error(_(u"INTERNAL ERROR: ") + err_msg) | 300 log.error(_("INTERNAL ERROR: ") + err_msg) |
301 raise MaildirError(err_msg) | 301 raise MaildirError(err_msg) |
302 if signal not in self.__observed[(profile, boxname)]: | 302 if signal not in self.__observed[(profile, boxname)]: |
303 err_msg = _(u"Trying to remove an inexistant observer, no observer for this signal") | 303 err_msg = _("Trying to remove an inexistant observer, no observer for this signal") |
304 log.error(_(u"INTERNAL ERROR: ") + err_msg) | 304 log.error(_("INTERNAL ERROR: ") + err_msg) |
305 raise MaildirError(err_msg) | 305 raise MaildirError(err_msg) |
306 if not callback in self.__observed[(profile, boxname)][signal]: | 306 if not callback in self.__observed[(profile, boxname)][signal]: |
307 err_msg = _(u"Trying to remove an inexistant observer") | 307 err_msg = _("Trying to remove an inexistant observer") |
308 log.error(_(u"INTERNAL ERROR: ") + err_msg) | 308 log.error(_("INTERNAL ERROR: ") + err_msg) |
309 raise MaildirError(err_msg) | 309 raise MaildirError(err_msg) |
310 self.__observed[(profile, boxname)][signal].remove(callback) | 310 self.__observed[(profile, boxname)][signal].remove(callback) |
311 | 311 |
312 def emitSignal(self, profile, boxname, signal_name): | 312 def emitSignal(self, profile, boxname, signal_name): |
313 """Emit the signal to observer""" | 313 """Emit the signal to observer""" |
314 log.debug(u'emitSignal %s %s %s' % (profile, boxname, signal_name)) | 314 log.debug('emitSignal %s %s %s' % (profile, boxname, signal_name)) |
315 try: | 315 try: |
316 for observer_cb in self.__observed[(profile, boxname)][signal_name]: | 316 for observer_cb in self.__observed[(profile, boxname)][signal_name]: |
317 observer_cb() | 317 observer_cb() |
318 except KeyError: | 318 except KeyError: |
319 pass | 319 pass |
345 """@param _maildir: the main MaildirBox instance | 345 """@param _maildir: the main MaildirBox instance |
346 @param name: name of the mailbox | 346 @param name: name of the mailbox |
347 @param profile: real profile (ie not a profile_key) | 347 @param profile: real profile (ie not a profile_key) |
348 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" | 348 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" |
349 if _maildir._checkBoxReference(name, profile): | 349 if _maildir._checkBoxReference(name, profile): |
350 log.error(u"INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") | 350 log.error("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") |
351 raise MaildirError('double MailboxUser instanciation') | 351 raise MaildirError('double MailboxUser instanciation') |
352 if name != "INBOX": | 352 if name != "INBOX": |
353 raise NotImplementedError | 353 raise NotImplementedError |
354 self.name = name | 354 self.name = name |
355 self.profile = profile | 355 self.profile = profile |
356 self.maildir = _maildir | 356 self.maildir = _maildir |
357 profile_path = self.maildir._getProfilePath(profile) | 357 profile_path = self.maildir._getProfilePath(profile) |
358 full_profile_path = os.path.join(self.maildir.host.memory.getConfig('', 'local_dir'), 'maildir', profile_path) | 358 full_profile_path = os.path.join(self.maildir.host.memory.getConfig('', 'local_dir'), 'maildir', profile_path) |
359 if not os.path.exists(full_profile_path): | 359 if not os.path.exists(full_profile_path): |
360 os.makedirs(full_profile_path, 0700) | 360 os.makedirs(full_profile_path, 0o700) |
361 mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH) | 361 mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH) |
362 self.mailbox_path = mailbox_path | 362 self.mailbox_path = mailbox_path |
363 self.mailbox = maildir.MaildirMailbox(mailbox_path) | 363 self.mailbox = maildir.MaildirMailbox(mailbox_path) |
364 self.observer = observer | 364 self.observer = observer |
365 self.__uid_table_update() | 365 self.__uid_table_update() |
366 | 366 |
367 if observer: | 367 if observer: |
368 log.debug(u"adding observer for %s (%s)" % (name, profile)) | 368 log.debug("adding observer for %s (%s)" % (name, profile)) |
369 self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE") | 369 self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE") |
370 | 370 |
371 def __uid_table_update(self): | 371 def __uid_table_update(self): |
372 existant_id = [] | 372 existant_id = [] |
373 for mess_idx in range(self.getMessageCount()): | 373 for mess_idx in range(self.getMessageCount()): |
376 self.getUid(mess_idx) | 376 self.getUid(mess_idx) |
377 self.maildir.cleanTable(self.name, existant_id, profile=self.profile) | 377 self.maildir.cleanTable(self.name, existant_id, profile=self.profile) |
378 | 378 |
379 def __del__(self): | 379 def __del__(self): |
380 if self.observer: | 380 if self.observer: |
381 log.debug(u"removing observer for %s" % self.name) | 381 log.debug("removing observer for %s" % self.name) |
382 self._maildir.removeObserver(self.observer, self.name, "NEW_MESSAGE") | 382 self._maildir.removeObserver(self.observer, self.name, "NEW_MESSAGE") |
383 self.maildir._removeBoxAccess(self.name, self, profile=self.profile) | 383 self.maildir._removeBoxAccess(self.name, self, profile=self.profile) |
384 | 384 |
385 def addMessage(self, message): | 385 def addMessage(self, message): |
386 """Add a message to the box | 386 """Add a message to the box |
488 def removeDeleted(self): | 488 def removeDeleted(self): |
489 """Actually delete message flagged "\\Deleted" | 489 """Actually delete message flagged "\\Deleted" |
490 Also purge the internal data of these messages | 490 Also purge the internal data of these messages |
491 """ | 491 """ |
492 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): | 492 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): |
493 print ("Deleting %s" % mess_id) | 493 print(("Deleting %s" % mess_id)) |
494 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) | 494 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) |
495 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) # We need to reparse the dir to have coherent indexing | 495 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) # We need to reparse the dir to have coherent indexing |
496 self.maildir.purgeDeleted(self.name, profile=self.profile) | 496 self.maildir.purgeDeleted(self.name, profile=self.profile) |
497 | 497 |
498 def emptyTrash(self): | 498 def emptyTrash(self): |