From 0a254081991a29a000991465b18edb2d97602eba Mon Sep 17 00:00:00 2001 From: Sebastian Spaeth Date: Mon, 22 Aug 2011 12:21:11 +0200 Subject: [PATCH] Rework undocumented listjoin to create UID sequences This function was badly named and completely undocumented. Rework it to avoid copying the full UID list using an iterator. Make it possible to hand it a list of UIDs as strings rather than implicitely relying on the fact that they are numeric already. Document the code. The behavior off the function itself remained otherwise unchanged. Signed-off-by: Sebastian Spaeth Signed-off-by: Nicolas Sebrecht --- offlineimap/folder/Gmail.py | 2 +- offlineimap/folder/IMAP.py | 2 +- offlineimap/imaputil.py | 44 ++++++++++++++++++------------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/offlineimap/folder/Gmail.py b/offlineimap/folder/Gmail.py index 6cd3446..3ca11cd 100644 --- a/offlineimap/folder/Gmail.py +++ b/offlineimap/folder/Gmail.py @@ -54,7 +54,7 @@ class GmailFolder(IMAPFolder): try: imapobj.select(self.getfullname()) result = imapobj.uid('copy', - imaputil.listjoin(uidlist), + imaputil.uid_sequence(uidlist), self.trash_folder) assert result[0] == 'OK', \ "Bad IMAPlib result: %s" % result[0] diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py index 40eb31c..dec14ae 100644 --- a/offlineimap/folder/IMAP.py +++ b/offlineimap/folder/IMAP.py @@ -638,7 +638,7 @@ class IMAPFolder(BaseFolder): self.ui.flagstoreadonly(self, uidlist, flags) return r = imapobj.uid('store', - imaputil.listjoin(uidlist), + imaputil.uid_sequence(uidlist), operation + 'FLAGS', imaputil.flagsmaildir2imap(flags)) assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1]) diff --git a/offlineimap/imaputil.py b/offlineimap/imaputil.py index 80a2486..94d6ffc 100644 --- a/offlineimap/imaputil.py +++ b/offlineimap/imaputil.py @@ -188,33 +188,31 @@ def flagsmaildir2imap(maildirflaglist): retval.sort() return '(' + ' '.join(retval) + ')' -def listjoin(list): - start = None - end = None - retval = [] +def uid_sequence(uidlist): + """Collapse UID lists into shorter sequence sets - def getlist(start, end): + [1,2,3,4,5,10,12,13] will return "1:5,10,12:13". This function does + not sort the list, and only collapses if subsequent entries form a + range. + :returns: The collapsed UID list as string""" + def getrange(start, end): if start == end: return(str(start)) - else: - return(str(start) + ":" + str(end)) - + return "%s:%s" % (start, end) - for item in list: - if start == None: - # First item. - start = item - end = item - elif item == end + 1: - # An addition to the list. - end = item - else: - # Here on: starting a new list. - retval.append(getlist(start, end)) - start = item - end = item + if not len(uidlist): return '' # Empty list, return + start, end = None, None + retval = [] - if start != None: - retval.append(getlist(start, end)) + for item in iter(uidlist): + item = int(item) + if start == None: # First item + start, end = item, item + elif item == end + 1: # Next item in a range + end = item + else: # Starting a new range + retval.append(getrange(start, end)) + start, end = item, item + retval.append(getrange(start, end)) # Add final range/item return ",".join(retval)