From 788056452052bb87082ad403b54cb9bdd2ff6861 Mon Sep 17 00:00:00 2001 From: jgoerzen Date: Thu, 18 Jul 2002 01:51:03 +0100 Subject: [PATCH] /offlineimap/head: changeset 131 Fixed problems when a UID is not forthcoming from a server after uploading a message. --- offlineimap/head/debian/changelog | 4 ++++ offlineimap/head/offlineimap.1 | 15 ++++++++++++++ offlineimap/head/offlineimap/folder/Base.py | 22 +++++++++++++-------- offlineimap/head/offlineimap/folder/IMAP.py | 17 +++++++++++++--- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/offlineimap/head/debian/changelog b/offlineimap/head/debian/changelog index c6ce54a..b9c5e38 100644 --- a/offlineimap/head/debian/changelog +++ b/offlineimap/head/debian/changelog @@ -4,6 +4,10 @@ offlineimap (3.0.2) unstable; urgency=low than remotefolder.getvisiblename() * Fixed remotepassfile option. Closes: #153119. Used 1-line patch from Tommi Virtanen. + * Now handles cases of not being able to get UID for an uploaded message + more gracefully. This could occur if the server doesn't support + SEARCH, can't find the message ID, or finds multiple message IDs. + Closes: #153241. -- John Goerzen Mon, 15 Jul 2002 19:43:36 -0500 diff --git a/offlineimap/head/offlineimap.1 b/offlineimap/head/offlineimap.1 index 4e9f118..53c675d 100644 --- a/offlineimap/head/offlineimap.1 +++ b/offlineimap/head/offlineimap.1 @@ -500,6 +500,21 @@ this as an intentional deletion of many messages and will interpret your action as requesting them to be deleted from the server as well. (If you don't understand this, don't worry; you probably won't encounter this situation) +.SS COPYING MESSAGES BETWEEN FOLDERS +Normally, when you copy a message between folders or add a new message +to a folder locally, +.B OfflineIMAP +will just do the right thing. However, sometimes this can be tricky +-- if your IMAP server does not provide the SEARCH command, or does +not return something useful, +.B OfflineIMAP +cannot determine the new UID of the message. So, in these rare +instances, OfflineIMAP will upload the message to the IMAP server and +delete it from your local folder. Then, on your next sync, the +message will be re-downloaded with the proper UID. +.B OfflineIMAP +makes sure that the message was properly uploaded before deleting it, +so there should be no risk of data loss. .SS MAILING LIST There is an OfflineIMAP mailing list available. .PP diff --git a/offlineimap/head/offlineimap/folder/Base.py b/offlineimap/head/offlineimap/folder/Base.py index 0f59a1f..8c25aef 100644 --- a/offlineimap/head/offlineimap/folder/Base.py +++ b/offlineimap/head/offlineimap/folder/Base.py @@ -94,6 +94,10 @@ class BaseFolder: If the backend cannot assign a new uid, it returns the uid passed in WITHOUT saving the message. + + If the backend CAN assign a new uid, but cannot find out what this UID + is (as is the case with many IMAP servers), it returns 0 but DOES save + the message. IMAP backend should be the only one that can assign a new uid. @@ -160,18 +164,20 @@ class BaseFolder: flags = self.getmessageflags(uid) for tryappend in applyto: successuid = tryappend.savemessage(uid, message, flags) - if successuid > 0: + if successuid >= 0: successobject = tryappend break # Did we succeed? if successobject != None: - # Copy the message to the other remote servers. - for appendserver in [x for x in applyto if x != successobject]: - appendserver.savemessage(successuid, message, flags) - # Copy it to its new name on the local server and delete - # the one without a UID. - self.savemessage(successuid, message, flags) - self.deletemessage(uid) + if successuid: # Only if IMAP actually assigned a UID + # Copy the message to the other remote servers. + for appendserver in \ + [x for x in applyto if x != successobject]: + appendserver.savemessage(successuid, message, flags) + # Copy to its new name on the local server and delete + # the one without a UID. + self.savemessage(successuid, message, flags) + self.deletemessage(uid) # It'll be re-downloaded. else: # Did not find any server to take this message. Ignore. pass diff --git a/offlineimap/head/offlineimap/folder/IMAP.py b/offlineimap/head/offlineimap/folder/IMAP.py index 441c00d..85c15e0 100644 --- a/offlineimap/head/offlineimap/folder/IMAP.py +++ b/offlineimap/head/offlineimap/folder/IMAP.py @@ -22,6 +22,8 @@ import rfc822 from StringIO import StringIO from copy import copy +import __main__ + class IMAPFolder(BaseFolder): def __init__(self, imapserver, name, visiblename, accountname): self.name = imaputil.dequote(name) @@ -114,11 +116,20 @@ class IMAPFolder(BaseFolder): # Checkpoint. Let it write out the messages, etc. assert(imapobj.check()[0] == 'OK') # Now find the UID it got. - matchinguids = imapobj.uid('search', None, - '(HEADER Message-Id %s)' % mid)[1][0] + try: + matchinguids = imapobj.uid('search', None, + '(HEADER Message-Id %s)' % mid)[1][0] + except imapobj.error: + # IMAP server doesn't implement search or had a problem. + return 0 matchinguids = matchinguids.split(' ') + if len(matchinguids) != 1 or matchinguids[0] == None: + return 0 matchinguids.sort() - uid = long(matchinguids[-1]) + try: + uid = long(matchinguids[-1]) + except ValueError: + return 0 self.messagelist[uid] = {'uid': uid, 'flags': flags} return uid finally: