[PATCH 3/4] IMAP: revamp _msgs_to_fetch()
Nicolas Sebrecht
nicolas.s-dev at laposte.net
Wed Mar 25 04:42:29 GMT 2015
Signed-off-by: Nicolas Sebrecht <nicolas.s-dev at laposte.net>
---
offlineimap/folder/IMAP.py | 96 +++++++++++++---------------------------------
1 file changed, 27 insertions(+), 69 deletions(-)
diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py
index bf61ebe..834b446 100644
--- a/offlineimap/folder/IMAP.py
+++ b/offlineimap/folder/IMAP.py
@@ -153,94 +153,52 @@ class IMAPFolder(BaseFolder):
Arguments:
- imapobj: instance of IMAPlib
- maxage (optional): only fetch messages up to maxage days ago
- - min_uid (optional): only fetch messages with uid > min_uid
+ - min_uid (optional): only fetch messages with UID >= min_uid
- This function should be called with at most one of maxage or
- min_uid.
-
- If using maxage, this finds the min uid of all messages within
- maxage, and returns all messages with uid > this min. As maxage
- is only set if this folder is the local folder, this ensures
- consistency with remote (which only restricts to uid > this min)
- in edge cases where the date is much earlier than messages with
- similar UID's (e.g. the UID was reassigned much later).
+ This function should be called with at MOST one of maxage OR
+ min_uid set but not BOTH.
Returns: range(s) for messages or None if no messages
are to be fetched."""
res_type, imapdata = imapobj.select(self.getfullname(), True, True)
if imapdata == [None] or imapdata[0] == '0':
- # Empty folder, no need to populate message list
+ # Empty folder, no need to populate message list.
return None
- # By default examine all messages in this folder
- msgsToFetch = '1:*'
+ conditions = []
+
+ if min_uid != None:
+ conditions.append("UID %d:*"% min_uid)
+ elif maxage != None:
+ # Find out what the oldest message is that we should look at.
+ oldest_struct = time.gmtime(time.time() - (60*60*24*maxage))
+ if oldest_struct[0] < 1900:
+ raise OfflineImapError("maxage setting led to year %d. "
+ "Abort syncing."% oldest_struct[0],
+ OfflineImapError.ERROR.REPO)
+ conditions.append("SINCE %02d-%s-%d"%
+ oldest_struct[2],
+ MonthNames[oldest_struct[1]],
+ oldest_struct[0])
maxsize = self.getmaxsize()
+ if maxsize != None:
+ conditions.append("SMALLER %d"% maxsize)
- # Build search condition
- if maxage or min_uid != None or maxsize != None:
- search_cond = "(";
-
- if maxage:
- #find out what the oldest message is that we should look at
- oldest_struct = time.gmtime(time.time() - (60*60*24*maxage))
- if oldest_struct[0] < 1900:
- raise OfflineImapError("maxage setting led to year %d. "
- "Abort syncing."% oldest_struct[0],
- OfflineImapError.ERROR.REPO)
- search_cond += "SINCE %02d-%s-%d"% (
- oldest_struct[2],
- MonthNames[oldest_struct[1]],
- oldest_struct[0])
- if min_uid != None:
- if maxage: # There are two conditions, add space
- search_cond += " "
- search_cond += "UID %d:*"% min_uid
-
- if maxsize != None:
- if maxage or min_uid != None:
- # There are at least two conditions, add space
- search_cond += " "
- search_cond += "SMALLER %d"% maxsize
-
- search_cond += ")"
-
+ if len(conditions) > 1:
+ # Build SEARCH conditions.
+ search_cond = "(%s)"% ' '.join(conditions)
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)
-
- if maxage:
- # Found messages within maxage, but want all messages with UID
- # > the min uid of the within-maxage messages. Ordering by UID
- # is the same as ordering by MSN, so we get the messages with
- # MSN > the min MSN of the within-maxage messages.
- msg_seq_numbers = map(lambda s : int(s), res_data[0].split())
- if msg_seq_numbers:
- min_msn = min(msg_seq_numbers)
- else:
- return None
- if maxsize == None:
- # If no maxsize, can just ask for all messages with MSN > min_msn
- return "%d:*"% min_msn
- else:
- # Restrict the range min_msn:* to those with acceptable size.
- # Single-quotes prevent imaplib2 from quoting the sequence.
- search_cond = "'%d:* (SMALLER %d)'"% (min_msn, maxsize)
- 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)
-
# Resulting MSN are separated by space, coalesce into ranges
- msgsToFetch = imaputil.uid_sequence(res_data[0].split())
-
- return msgsToFetch
+ return imaputil.uid_sequence(res_data[0].split())
+ # By default examine all messages in this folder.
+ return '1:*'
# Interface from BaseFolder
def msglist_item_initializer(self, uid):
--
2.3.1
More information about the OfflineIMAP-project
mailing list