[PATCH 2/4] Factor out the date guessing/retrieving
Sebastian Spaeth
Sebastian at SSpaeth.de
Tue Jan 25 09:25:53 GMT 2011
savemessage was too long and complex. Factor out the date guessing part
of the function and put it into a function of its own. The logic of the
date guessing is the same, however we don't need to run all our
datetuples through imaplib.Time2InternalDate() as the imaplib.append()
will do this for us.
Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
offlineimap/folder/IMAP.py | 69 ++++++++++++++++++++++++++++++++++++++-----
1 files changed, 61 insertions(+), 8 deletions(-)
diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py
index 37fc652..f5fd490 100644
--- a/offlineimap/folder/IMAP.py
+++ b/offlineimap/folder/IMAP.py
@@ -300,24 +300,77 @@ class IMAPFolder(BaseFolder):
matchinguids.sort()
return long(matchinguids[0])
+
+ def getmessagedate(self, content, rtime=None):
+ """Parses mail and returns an 9-datetuple
+
+ It will use information in the following order, falling back as an attempt fails:
+ - rtime parameter
+ - Date header of email
+ - Local system time
+ :param rtime: epoch timestamp to be used rather than analyzing
+ the email.
+ :returns: 9-tuple that can be passed directly to time.mktime()
+ or None in case of failure. Indexes 6, 7, and 8 are not usable."""
+ if rtime is None:
+ message = rfc822.Message(StringIO(content))
+ # parsedate returns a 9-tuple that can be passed directly to
+ # time.mktime(); Will be None if missing or not in a valid
+ # format. Note that indexes 6, 7, and 8 of the result tuple are
+ # not usable.
+ datetuple = rfc822.parsedate(message.getheader('Date'))
+
+ if datetuple is None:
+ #could not determine the date, use the local time.
+ datetuple = time.localtime()
+ else:
+ #rtime is set, use that instead
+ datetuple = time.localtime(rtime)
+
+ try:
+ # Check for invalid dates
+ if datetuple[0] < 1981:
+ raise ValueError
+
+ # Check for invalid dates
+ datetuple_check = time.localtime(time.mktime(datetuple))
+ if datetuple[:2] != datetuple_check[:2]:
+ raise ValueError
+
+ except (ValueError, OverflowError):
+ # Argh, sometimes it's a valid format but year is 0102
+ # or something. Argh. It seems that Time2Internaldate
+ # will rause a ValueError if the year is 0102 but not 1902,
+ # but some IMAP servers nonetheless choke on 1902.
+ self.ui.debug("Message with invalid date %s. Using local time." % datetuple)
+ datetuple = time.localtime()
+
+ return datetuple
+
def savemessage(self, uid, content, flags, rtime):
+ """Save the message on the Server
+
+ This backend always assigns a new uid, so the uid arg is ignored.
+
+ This function will update the self.messagelist dict to contain
+ the new message after sucessfully saving it.
+
+ :param rtime: A timestamp to be
+ :returns: the UID of the new message as assigned by the
+ server. If the folder is read-only it will return 0."""
imapobj = self.imapserver.acquireconnection()
self.ui.debug('imap', 'savemessage: called')
+
try:
try:
imapobj.select(self.getfullname()) # Needed for search
except imapobj.readonly:
self.ui.msgtoreadonly(self, uid, content, flags)
# Return indicating message taken, but no UID assigned.
- # Fudge it.
return 0
- # This backend always assigns a new uid, so the uid arg is ignored.
- # In order to get the new uid, we need to save off the message ID.
-
- message = rfc822.Message(StringIO(content))
- datetuple_msg = rfc822.parsedate(message.getheader('Date'))
- # Will be None if missing or not in a valid format.
+ # get the date of the message file, so we can pass it to the server.
+ date = self.getmessagedate(content, rtime)
# If time isn't known
if rtime == None and datetuple_msg == None:
@@ -345,7 +398,7 @@ class IMAPFolder(BaseFolder):
# but some IMAP servers nonetheless choke on 1902.
date = imaplib.Time2Internaldate(time.localtime())
- self.ui.debug('imap', 'savemessage: using date ' + str(date))
+ self.ui.debug('imap', 'savemessage: using date %s' % date)
content = re.sub("(?<!\r)\n", "\r\n", content)
self.ui.debug('imap', 'savemessage: initial content is: ' + repr(content))
--
1.7.1
More information about the OfflineIMAP-project
mailing list