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 <Sebastian@SSpaeth.de>
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Sebastian Spaeth 2011-08-22 12:21:11 +02:00 committed by Nicolas Sebrecht
parent 3302940382
commit fb8017991c
3 changed files with 23 additions and 25 deletions

View File

@ -55,7 +55,7 @@ class GmailFolder(IMAPFolder):
try: try:
imapobj.select(self.getfullname()) imapobj.select(self.getfullname())
result = imapobj.uid('copy', result = imapobj.uid('copy',
imaputil.listjoin(uidlist), imaputil.uid_sequence(uidlist),
self.trash_folder) self.trash_folder)
assert result[0] == 'OK', \ assert result[0] == 'OK', \
"Bad IMAPlib result: %s" % result[0] "Bad IMAPlib result: %s" % result[0]

View File

@ -626,7 +626,7 @@ class IMAPFolder(BaseFolder):
self.ui.flagstoreadonly(self, uidlist, flags) self.ui.flagstoreadonly(self, uidlist, flags)
return return
r = imapobj.uid('store', r = imapobj.uid('store',
imaputil.listjoin(uidlist), imaputil.uid_sequence(uidlist),
operation + 'FLAGS', operation + 'FLAGS',
imaputil.flagsmaildir2imap(flags)) imaputil.flagsmaildir2imap(flags))
assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1]) assert r[0] == 'OK', 'Error with store: ' + '. '.join(r[1])

View File

@ -168,35 +168,33 @@ def flagsmaildir2imap(maildirflaglist):
retval.sort() retval.sort()
return '(' + ' '.join(retval) + ')' return '(' + ' '.join(retval) + ')'
def listjoin(list): def uid_sequence(uidlist):
start = None """Collapse UID lists into shorter sequence sets
end = None
retval = []
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: if start == end:
return(str(start)) return(str(start))
else: return "%s:%s" % (start, end)
return(str(start) + ":" + str(end))
if not len(uidlist): return '' # Empty list, return
start, end = None, None
retval = []
for item in list: for item in iter(uidlist):
if start == None: item = int(item)
# First item. if start == None: # First item
start = item start, end = item, item
end = item elif item == end + 1: # Next item in a range
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 end = item
else: # Starting a new range
retval.append(getrange(start, end))
start, end = item, item
if start != None: retval.append(getrange(start, end)) # Add final range/item
retval.append(getlist(start, end))
return ",".join(retval) return ",".join(retval)