Merge branch 'ss/better-error-throwing-and-id-sequence' into next
Conflicts: offlineimap/folder/IMAP.py offlineimap/imaputil.py Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
commit
67863017e2
@ -110,76 +110,70 @@ class IMAPFolder(BaseFolder):
|
||||
self.imapserver.releaseconnection(imapobj)
|
||||
return False
|
||||
|
||||
# TODO: Make this so that it can define a date that would be the oldest messages etc.
|
||||
def cachemessagelist(self):
|
||||
imapobj = self.imapserver.acquireconnection()
|
||||
maxage = self.config.getdefaultint("Account %s" % self.accountname,
|
||||
"maxage", -1)
|
||||
maxsize = self.config.getdefaultint("Account %s" % self.accountname,
|
||||
"maxsize", -1)
|
||||
self.messagelist = {}
|
||||
|
||||
imapobj = self.imapserver.acquireconnection()
|
||||
try:
|
||||
# Primes untagged_responses
|
||||
imaptype, imapdata = imapobj.select(self.getfullname(), readonly = 1, force = 1)
|
||||
res_type, imapdata = imapobj.select(self.getfullname(), True)
|
||||
|
||||
maxage = self.config.getdefaultint("Account " + self.accountname, "maxage", -1)
|
||||
maxsize = self.config.getdefaultint("Account " + self.accountname, "maxsize", -1)
|
||||
# By default examine all UIDs in this folder
|
||||
msgsToFetch = '1:*'
|
||||
|
||||
if (maxage != -1) | (maxsize != -1):
|
||||
try:
|
||||
search_condition = "(";
|
||||
search_cond = "(";
|
||||
|
||||
if(maxage != -1):
|
||||
#find out what the oldest message is that we should look at
|
||||
oldest_time_struct = time.gmtime(time.time() - (60*60*24*maxage))
|
||||
oldest_struct = time.gmtime(time.time() - (60*60*24*maxage))
|
||||
|
||||
#format this manually - otherwise locales could cause problems
|
||||
monthnames_standard = ["Jan", "Feb", "Mar", "Apr", "May", \
|
||||
#format months manually - otherwise locales cause problems
|
||||
monthnames = ["Jan", "Feb", "Mar", "Apr", "May", \
|
||||
"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
|
||||
our_monthname = monthnames_standard[oldest_time_struct[1]-1]
|
||||
daystr = "%(day)02d" % {'day' : oldest_time_struct[2]}
|
||||
date_search_str = "SINCE " + daystr + "-" + our_monthname \
|
||||
+ "-" + str(oldest_time_struct[0])
|
||||
month = monthnames[oldest_struct[1]-1]
|
||||
daystr = "%(day)02d" % {'day' : oldest_struct[2]}
|
||||
|
||||
search_condition += date_search_str
|
||||
search_cond += "SINCE %s-%s-%s" % (daystr, month,
|
||||
oldest_struct[0])
|
||||
|
||||
if(maxsize != -1):
|
||||
if(maxage != -1): #There are two conditions - add a space
|
||||
search_condition += " "
|
||||
if(maxage != -1): # There are two conditions, add space
|
||||
search_cond += " "
|
||||
search_cond += "SMALLER %d" % maxsize
|
||||
|
||||
search_condition += "SMALLER " + self.config.getdefault("Account " + self.accountname, "maxsize", -1)
|
||||
search_cond += ")"
|
||||
|
||||
search_condition += ")"
|
||||
searchresult = imapobj.search(None, search_condition)
|
||||
res_type, res_data = imapobj.search(None, search_cond)
|
||||
if res_type != 'OK':
|
||||
raise OfflineImapError("SEARCH in folder [%s]%s failed. "
|
||||
"Search string was '%s'. Server responded '[%s] %s'" % (
|
||||
self.getrepository(), self,
|
||||
search_cond, res_type, res_data),
|
||||
OfflineImapError.ERROR.FOLDER)
|
||||
|
||||
#result would come back seperated by space - to change into a fetch
|
||||
#statement we need to change space to comma
|
||||
messagesToFetch = searchresult[1][0].replace(" ", ",")
|
||||
except KeyError:
|
||||
return
|
||||
if len(messagesToFetch) < 1:
|
||||
# No messages; return
|
||||
return
|
||||
else:
|
||||
# 1. Some mail servers do not return an EXISTS response
|
||||
# if the folder is empty. 2. ZIMBRA servers can return
|
||||
# multiple EXISTS replies in the form 500, 1000, 1500,
|
||||
# 1623 so check for potentially multiple replies.
|
||||
if imapdata == [None]:
|
||||
return
|
||||
# Result UIDs are seperated by space, coalesce into ranges
|
||||
msgsToFetch = imaputil.uid_sequence(res_data.split())
|
||||
if not msgsToFetch:
|
||||
return # No messages to sync
|
||||
|
||||
maxmsgid = 0
|
||||
for msgid in imapdata:
|
||||
maxmsgid = max(long(msgid), maxmsgid)
|
||||
if maxmsgid < 1:
|
||||
#no messages; return
|
||||
return
|
||||
messagesToFetch = '1:%d' % maxmsgid;
|
||||
|
||||
# Now, get the flags and UIDs for these.
|
||||
# We could conceivably get rid of maxmsgid and just say
|
||||
# '1:*' here.
|
||||
response = imapobj.fetch(messagesToFetch, '(FLAGS UID)')[1]
|
||||
# Get the flags and UIDs for these. single-quotes prevent
|
||||
# imaplib2 from quoting the sequence.
|
||||
res_type, response = imapobj.fetch("'%s'" % msgsToFetch,
|
||||
'(FLAGS UID)')
|
||||
if res_type != 'OK':
|
||||
raise OfflineImapError("FETCHING UIDs in folder [%s]%s failed. "
|
||||
"Server responded '[%s] %s'" % (
|
||||
self.getrepository(), self,
|
||||
res_type, response),
|
||||
OfflineImapError.ERROR.FOLDER)
|
||||
finally:
|
||||
self.imapserver.releaseconnection(imapobj)
|
||||
|
||||
for messagestr in response:
|
||||
# looks like: '1 (FLAGS (\\Seen Old) UID 4807)' or None if no msg
|
||||
# Discard initial message number.
|
||||
|
@ -191,10 +191,8 @@ def flagsmaildir2imap(maildirflaglist):
|
||||
def uid_sequence(uidlist):
|
||||
"""Collapse UID lists into shorter sequence sets
|
||||
|
||||
[1,2,3,4,5,10,12,13] will return "1:5,10,12:13". This function
|
||||
converts items to numeric type and sorts the list to always produce
|
||||
the minimal collapsed set.
|
||||
|
||||
[1,2,3,4,5,10,12,13] will return "1:5,10,12:13". This function sorts
|
||||
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:
|
||||
@ -208,6 +206,7 @@ def uid_sequence(uidlist):
|
||||
sorted_uids = sorted(map(int, uidlist))
|
||||
|
||||
for item in iter(sorted_uids):
|
||||
item = int(item)
|
||||
if start == None: # First item
|
||||
start, end = item, item
|
||||
elif item == end + 1: # Next item in a range
|
||||
|
Loading…
Reference in New Issue
Block a user