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)