[PATCH 2/4] Re: Factor out the date guessing/retrieving

Nicolas Sebrecht nicolas.s-dev at laposte.net
Fri Jan 21 21:43:02 UTC 2011


On Fri, Jan 21, 2011 at 03:09:05PM +0100, Sebastian Spaeth wrote:
> 
> 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.

Looks good. While touching this area, we could try to improve the code
(I don't mean in this particular commit).

> Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
> ---
>  offlineimap/folder/IMAP.py |   95 ++++++++++++++++++++++++++++----------------
>  1 files changed, 61 insertions(+), 34 deletions(-)
> 
> diff --git a/offlineimap/folder/IMAP.py b/offlineimap/folder/IMAP.py
> index e4e7f06..494e309 100644
> --- a/offlineimap/folder/IMAP.py
> +++ b/offlineimap/folder/IMAP.py
> @@ -295,53 +295,80 @@ 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.
> +            UIBase.getglobalui().debug("Message with invalid date %s" % datetuple)

I'm thinking of

  UIBase.getglobalui().debug("Message with invalid date %s, using local time instead." % datetuple)

but it would be even better if we could give the Message-ID or something
to help user do his own check and repair.


> +            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.

Why ask for it, then?


-- 
Nicolas Sebrecht



More information about the OfflineIMAP-project mailing list