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 8de326b29f
commit 0a25408199
3 changed files with 23 additions and 25 deletions

View File

@ -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]

View File

@ -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])

View File

@ -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)