Simplify MappedIMAPFolder, fixing bugs
Previously, we instanciated an MappedImapFolder, and would cleverly (too cleverly?) invoke methods on it casting it to an IMAPFolder by calling methods such as: self._mb.cachemessages(self) where self._MB is the class IMAPFolder and self and instance of MappedImapFolder. If e.g. cachemessages() invokes a method uidexists() which exists for MappedImapFolder, but not directly in IMAPFolder, I am not sure if Python would at some point attempt to use the method of the wrong class. Also, this leads to some twisted thinking as our class would in same cases act as an IMAPFolder and in some cases as an MappedImapFOlder and it is not always clear if we mean REMOTE UID or LOCAL UID. This commit simplifies the class, by a)doing away with the complex Mixin construct and directly inheriting from IMAPFOlder (so we get all the IMAPFOlder methods that we can inherit). We instantiate self._mb as a new instance of IMAPFolder which represents the local IMAP using local UIDs, separating the MappedIMAPFolder construct logically from the IMAPFolder somewhat. In the long run, I would like to remove self._mb completely and simply override any method that needs overriding, but let us take small and understandable baby steps here. Reported-and-tested-by: Vincent Beffara <vbeffara@gmail.com> Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de> Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
b40d02e801
commit
3ce514e92b
@ -20,8 +20,11 @@ from threading import *
|
|||||||
from IMAP import IMAPFolder
|
from IMAP import IMAPFolder
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
class MappingFolderMixIn:
|
class MappedIMAPFolder(IMAPFolder):
|
||||||
"""Helper class to map between Folder() instances where both side assign a uid
|
"""IMAP class to map between Folder() instances where both side assign a uid
|
||||||
|
|
||||||
|
This Folder is used on the local side, while the remote side should
|
||||||
|
be an IMAPFolder.
|
||||||
|
|
||||||
Instance variables (self.):
|
Instance variables (self.):
|
||||||
r2l: dict mapping message uids: self.r2l[remoteuid]=localuid
|
r2l: dict mapping message uids: self.r2l[remoteuid]=localuid
|
||||||
@ -29,10 +32,13 @@ class MappingFolderMixIn:
|
|||||||
#TODO: what is the difference, how are they used?
|
#TODO: what is the difference, how are they used?
|
||||||
diskr2l: dict mapping message uids: self.r2l[remoteuid]=localuid
|
diskr2l: dict mapping message uids: self.r2l[remoteuid]=localuid
|
||||||
diskl2r: dict mapping message uids: self.r2l[localuid]=remoteuid"""
|
diskl2r: dict mapping message uids: self.r2l[localuid]=remoteuid"""
|
||||||
def _initmapping(self):
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
IMAPFolder.__init__(self, *args, **kwargs)
|
||||||
self.maplock = Lock()
|
self.maplock = Lock()
|
||||||
(self.diskr2l, self.diskl2r) = self._loadmaps()
|
(self.diskr2l, self.diskl2r) = self._loadmaps()
|
||||||
self._mb = self.__class__.__bases__[1]
|
self._mb = IMAPFolder(*args, **kwargs)
|
||||||
|
"""Representing the local IMAP Folder using local UIDs"""
|
||||||
|
|
||||||
def _getmapfilename(self):
|
def _getmapfilename(self):
|
||||||
return os.path.join(self.repository.getmapdir(),
|
return os.path.join(self.repository.getmapdir(),
|
||||||
@ -81,8 +87,8 @@ class MappingFolderMixIn:
|
|||||||
return [mapping[x] for x in items]
|
return [mapping[x] for x in items]
|
||||||
|
|
||||||
def cachemessagelist(self):
|
def cachemessagelist(self):
|
||||||
self._mb.cachemessagelist(self)
|
self._mb.cachemessagelist()
|
||||||
reallist = self._mb.getmessagelist(self)
|
reallist = self._mb.getmessagelist()
|
||||||
|
|
||||||
self.maplock.acquire()
|
self.maplock.acquire()
|
||||||
try:
|
try:
|
||||||
@ -137,7 +143,7 @@ class MappingFolderMixIn:
|
|||||||
cachemessagelist() before calling this function!"""
|
cachemessagelist() before calling this function!"""
|
||||||
|
|
||||||
retval = {}
|
retval = {}
|
||||||
localhash = self._mb.getmessagelist(self)
|
localhash = self._mb.getmessagelist()
|
||||||
self.maplock.acquire()
|
self.maplock.acquire()
|
||||||
try:
|
try:
|
||||||
for key, value in localhash.items():
|
for key, value in localhash.items():
|
||||||
@ -158,7 +164,7 @@ class MappingFolderMixIn:
|
|||||||
|
|
||||||
def getmessage(self, uid):
|
def getmessage(self, uid):
|
||||||
"""Returns the content of the specified message."""
|
"""Returns the content of the specified message."""
|
||||||
return self._mb.getmessage(self, self.r2l[uid])
|
return self._mb.getmessage(self.r2l[uid])
|
||||||
|
|
||||||
def savemessage(self, uid, content, flags, rtime):
|
def savemessage(self, uid, content, flags, rtime):
|
||||||
"""Writes a new message, with the specified uid.
|
"""Writes a new message, with the specified uid.
|
||||||
@ -185,7 +191,7 @@ class MappingFolderMixIn:
|
|||||||
self.savemessageflags(uid, flags)
|
self.savemessageflags(uid, flags)
|
||||||
return uid
|
return uid
|
||||||
|
|
||||||
newluid = self._mb.savemessage(self, -1, content, flags, rtime)
|
newluid = self._mb.savemessage(-1, content, flags, rtime)
|
||||||
if newluid < 1:
|
if newluid < 1:
|
||||||
raise ValueError("Backend could not find uid for message")
|
raise ValueError("Backend could not find uid for message")
|
||||||
self.maplock.acquire()
|
self.maplock.acquire()
|
||||||
@ -200,19 +206,19 @@ class MappingFolderMixIn:
|
|||||||
return uid
|
return uid
|
||||||
|
|
||||||
def getmessageflags(self, uid):
|
def getmessageflags(self, uid):
|
||||||
return self._mb.getmessageflags(self, self.r2l[uid])
|
return self._mb.getmessageflags(self.r2l[uid])
|
||||||
|
|
||||||
def getmessagetime(self, uid):
|
def getmessagetime(self, uid):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def savemessageflags(self, uid, flags):
|
def savemessageflags(self, uid, flags):
|
||||||
self._mb.savemessageflags(self, self.r2l[uid], flags)
|
self._mb.savemessageflags(self.r2l[uid], flags)
|
||||||
|
|
||||||
def addmessageflags(self, uid, flags):
|
def addmessageflags(self, uid, flags):
|
||||||
self._mb.addmessageflags(self, self.r2l[uid], flags)
|
self._mb.addmessageflags(self.r2l[uid], flags)
|
||||||
|
|
||||||
def addmessagesflags(self, uidlist, flags):
|
def addmessagesflags(self, uidlist, flags):
|
||||||
self._mb.addmessagesflags(self, self._uidlist(self.r2l, uidlist),
|
self._mb.addmessagesflags(self._uidlist(self.r2l, uidlist),
|
||||||
flags)
|
flags)
|
||||||
|
|
||||||
def _mapped_delete(self, uidlist):
|
def _mapped_delete(self, uidlist):
|
||||||
@ -233,22 +239,16 @@ class MappingFolderMixIn:
|
|||||||
self.maplock.release()
|
self.maplock.release()
|
||||||
|
|
||||||
def deletemessageflags(self, uid, flags):
|
def deletemessageflags(self, uid, flags):
|
||||||
self._mb.deletemessageflags(self, self.r2l[uid], flags)
|
self._mb.deletemessageflags(self.r2l[uid], flags)
|
||||||
|
|
||||||
def deletemessagesflags(self, uidlist, flags):
|
def deletemessagesflags(self, uidlist, flags):
|
||||||
self._mb.deletemessagesflags(self, self._uidlist(self.r2l, uidlist),
|
self._mb.deletemessagesflags(self._uidlist(self.r2l, uidlist),
|
||||||
flags)
|
flags)
|
||||||
|
|
||||||
def deletemessage(self, uid):
|
def deletemessage(self, uid):
|
||||||
self._mb.deletemessage(self, self.r2l[uid])
|
self._mb.deletemessage(self.r2l[uid])
|
||||||
self._mapped_delete([uid])
|
self._mapped_delete([uid])
|
||||||
|
|
||||||
def deletemessages(self, uidlist):
|
def deletemessages(self, uidlist):
|
||||||
self._mb.deletemessages(self, self._uidlist(self.r2l, uidlist))
|
self._mb.deletemessages(self._uidlist(self.r2l, uidlist))
|
||||||
self._mapped_delete(uidlist)
|
self._mapped_delete(uidlist)
|
||||||
|
|
||||||
# Define a class for local part of IMAP.
|
|
||||||
class MappedIMAPFolder(MappingFolderMixIn, IMAPFolder):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
IMAPFolder.__init__(self, *args, **kwargs)
|
|
||||||
self._initmapping()
|
|
||||||
|
Loading…
Reference in New Issue
Block a user