diff --git a/Changelog.rst b/Changelog.rst index c872055..95a13b8 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -12,6 +12,20 @@ ChangeLog releases announces. +OfflineIMAP v6.3.4 (2011-08-10) +=============================== + +Notes +----- + +Here we are. A nice release since v6.3.3, I think. + +Changes +------- + +* Handle when UID can't be found on saved messages. + + OfflineIMAP v6.3.4-rc4 (2011-07-27) =================================== diff --git a/docs/FAQ.rst b/docs/FAQ.rst index cebe766..3181a8a 100644 --- a/docs/FAQ.rst +++ b/docs/FAQ.rst @@ -189,6 +189,11 @@ Then, on your next sync, the message will be re-downloaded with the proper UID. `OfflineIMAP`_ makes sure that the message was properly uploaded before deleting it, so there should be no risk of data loss. +But if you try to sync between two IMAP servers, where both are unable to +provide you with UID of the new message, then this will lead to infinite loop. +`OfflineIMAP`_ will upload the message to one server and delete on second. On +next run it will upload the message to second server and delete on first, etc. + Does OfflineIMAP support POP? ----------------------------- diff --git a/offlineimap/__init__.py b/offlineimap/__init__.py index d35df7f..5070ac7 100644 --- a/offlineimap/__init__.py +++ b/offlineimap/__init__.py @@ -1,7 +1,7 @@ __all__ = ['OfflineImap'] __productname__ = 'OfflineIMAP' -__version__ = "6.3.4-rc4" +__version__ = "6.3.4" __copyright__ = "Copyright 2002-2011 John Goerzen & contributors" __author__ = "John Goerzen" __author_email__= "john@complete.org" diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py index 608d361..0d5ddae 100644 --- a/offlineimap/folder/Base.py +++ b/offlineimap/folder/Base.py @@ -264,6 +264,14 @@ class BaseFolder(object): uid = newuid # Save uploaded status in the statusfolder statusfolder.savemessage(uid, message, flags, rtime) + elif newuid == 0: + # Message was stored to dstfolder, but we can't find it's UID + # This means we can't link current message to the one created + # in IMAP. So we just delete local message and on next run + # we'll sync it back + # XXX This could cause infinite loop on syncing between two + # IMAP servers ... + self.deletemessage(uid) else: raise UserWarning("Trying to save msg (uid %d) on folder " "%s returned invalid uid %d" % \ diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 9297a7b..3c702f4 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -276,7 +276,7 @@ class IMAPFolder(BaseFolder): self.ui.debug('imap', 'savemessage_addheader: called to add %s: %s' % (headername, headervalue)) - insertionpoint = content.find("\r\n") + insertionpoint = content.find("\r\n\r\n") self.ui.debug('imap', 'savemessage_addheader: insertionpoint = %d' % insertionpoint) leader = content[0:insertionpoint] self.ui.debug('imap', 'savemessage_addheader: leader = %s' % repr(leader)) @@ -409,8 +409,10 @@ class IMAPFolder(BaseFolder): the new message after sucessfully saving it. :param rtime: A timestamp to be used as the mail date - :returns: the UID of the new message as assigned by the - server. If the folder is read-only it will return 0.""" + :returns: the UID of the new message as assigned by the server. If the + message is saved, but it's UID can not be found, it will + return 0. If the message can't be written (folder is + read-only for example) it will return -1.""" self.ui.debug('imap', 'savemessage: called') # already have it, just save modified flags @@ -504,7 +506,7 @@ class IMAPFolder(BaseFolder): return result = imapobj.uid('store', '%d' % uid, 'FLAGS', imaputil.flagsmaildir2imap(flags)) - assert result[0] == 'OK', 'Error with store: ' + '. '.join(r[1]) + assert result[0] == 'OK', 'Error with store: ' + '. '.join(result[1]) finally: self.imapserver.releaseconnection(imapobj) result = result[1][0]