Merge branch 'ss/uidmaps' into next

This commit is contained in:
Nicolas Sebrecht 2011-03-16 18:05:35 +01:00
commit 3eba44f636
3 changed files with 37 additions and 21 deletions

View File

@ -157,20 +157,21 @@ class BaseFolder:
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.
If the uid is < 0, the backend should assign a new uid and return it.
If the backend cannot assign a new uid, it returns the uid passed in If the uid is < 0: The backend should assign a new uid and
WITHOUT saving the message. return it. In case it cannot assign a new uid, it returns
the negative uid passed in WITHOUT saving the message.
If the backend CAN assign a new uid, but cannot find out what this UID If the backend CAN assign a new uid, but cannot find out what
is (as is the case with many IMAP servers), it returns 0 but DOES save this UID is (as is the case with some IMAP servers), it
the message. returns 0 but DOES save the message.
IMAP backend should be the only one that can assign a new uid. IMAP backend should be the only one that can assign a new
uid.
If the uid is > 0, the backend should set the uid to this, if it can. If the uid is > 0, the backend should set the uid to this, if it can.
If it cannot set the uid to that, it will save it anyway. If it cannot set the uid to that, it will save it anyway.
It will return the uid assigned in any case. It will return the uid assigned in any case.
""" """
raise NotImplementedException raise NotImplementedException

View File

@ -394,6 +394,11 @@ class IMAPFolder(BaseFolder):
server. If the folder is read-only it will return 0.""" server. If the folder is read-only it will return 0."""
self.ui.debug('imap', 'savemessage: called') self.ui.debug('imap', 'savemessage: called')
# already have it, just save modified flags
if uid > 0 and uid in self.messagelist:
self.savemessageflags(uid, flags)
return uid
try: try:
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()

View File

@ -21,6 +21,14 @@ from IMAP import IMAPFolder
import os.path import os.path
class MappingFolderMixIn: class MappingFolderMixIn:
"""Helper class to map between Folder() instances where both side assign a uid
Instance variables (self.):
r2l: dict mapping message uids: self.r2l[remoteuid]=localuid
l2r: dict mapping message uids: self.r2l[localuid]=remoteuid
#TODO: what is the difference, how are they used?
diskr2l: dict mapping message uids: self.r2l[remoteuid]=localuid
diskl2r: dict mapping message uids: self.r2l[localuid]=remoteuid"""
def _initmapping(self): def _initmapping(self):
self.maplock = Lock() self.maplock = Lock()
(self.diskr2l, self.diskl2r) = self._loadmaps() (self.diskr2l, self.diskl2r) = self._loadmaps()
@ -129,30 +137,32 @@ class MappingFolderMixIn:
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.
If the uid is < 0, the backend should assign a new uid and return it.
If the backend cannot assign a new uid, it returns the uid passed in The UIDMaps class will not return a newly assigned uid, as it
WITHOUT saving the message. internally maps different uids between IMAP servers. So a
successful savemessage() invocation will return the same uid it
If the backend CAN assign a new uid, but cannot find out what this UID has been invoked with. As it maps between 2 IMAP servers which
is (as is the case with many IMAP servers), it returns 0 but DOES save means the source message must already have an uid, it requires a
the message. positive uid to be passed in. Passing in a message with a
negative uid will do nothing and return the negative uid.
IMAP backend should be the only one that can assign a new uid.
If the uid is > 0, the backend should set the uid to this, if it can. If the uid is > 0, the backend should set the uid to this, if it can.
If it cannot set the uid to that, it will save it anyway. If it cannot set the uid to that, it will save it anyway.
It will return the uid assigned in any case. It will return the uid assigned in any case.
""" """
# Mapped UID instances require the source to already have a
# positive UID, so simply return here.
if uid < 0: if uid < 0:
# We cannot assign a new uid.
return uid return uid
#if msg uid already exists, just modify the flags
if uid in self.r2l: if uid in self.r2l:
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(self, -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()
try: try:
self.diskl2r[newluid] = uid self.diskl2r[newluid] = uid
@ -219,5 +229,5 @@ class MappingFolderMixIn:
# Define a class for local part of IMAP. # Define a class for local part of IMAP.
class MappedIMAPFolder(MappingFolderMixIn, IMAPFolder): class MappedIMAPFolder(MappingFolderMixIn, IMAPFolder):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
apply(IMAPFolder.__init__, (self,) + args, kwargs) IMAPFolder.__init__(self, *args, **kwargs)
self._initmapping() self._initmapping()