Add support for alternative message date synchronisation

Global or per-repository option utime_from_message tells OfflineIMAP
to set file modification time of messages pushed from one repository
to another basing on the message's "Date" header.

This is useful if you are doing some processing/finding on your
Maildir (for example, finding messages older than 3 months),
without parsing each file/message content.

From: Cyril RUSSO <boite.pour.spam@gmail.com>
Signed-off-by: Eygene Ryabinkin <rea@codelabs.ru>
This commit is contained in:
X-Ryl669
2013-01-17 14:21:21 +01:00
committed by Eygene Ryabinkin
parent e26827c1cb
commit 3bc66c0858
4 changed files with 60 additions and 16 deletions

View File

@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from offlineimap import threadutil
from offlineimap import threadutil, emailutil
from offlineimap import globals
from offlineimap.ui import getglobalui
from offlineimap.error import OfflineImapError
@ -48,6 +48,13 @@ class BaseFolder(object):
if self.visiblename == self.getsep():
self.visiblename = ''
self.config = repository.getconfig()
utime_from_message_global = \
self.config.getdefaultboolean("general",
"utime_from_message", False)
repo = "Repository " + repository.name
self._utime_from_message = \
self.config.getdefaultboolean(repo,
"utime_from_message", utime_from_message_global)
def getname(self):
"""Returns name"""
@ -66,6 +73,10 @@ class BaseFolder(object):
"""Should this folder be synced or is it e.g. filtered out?"""
return self._sync_this
@property
def utime_from_message(self):
return self._utime_from_message
def suggeststhreads(self):
"""Returns true if this folder suggests using threads for actions;
false otherwise. Probably only IMAP will return true."""
@ -327,6 +338,9 @@ class BaseFolder(object):
message = None
flags = self.getmessageflags(uid)
rtime = self.getmessagetime(uid)
if dstfolder.utime_from_message:
content = self.getmessage(uid)
rtime = emailutil.get_message_date(content, 'Date')
if uid > 0 and dstfolder.uidexists(uid):
# dst has message with that UID already, only update status

View File

@ -15,14 +15,13 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import email
import random
import binascii
import re
import time
from sys import exc_info
from .Base import BaseFolder
from offlineimap import imaputil, imaplibutil, OfflineImapError
from offlineimap import imaputil, imaplibutil, emailutil, OfflineImapError
from offlineimap import globals
from offlineimap.imaplib2 import MonthNames
@ -431,21 +430,12 @@ class IMAPFolder(BaseFolder):
:returns: string in the form of "DD-Mmm-YYYY HH:MM:SS +HHMM"
(including double quotes) or `None` in case of failure
(which is fine as value for append)."""
if rtime is None:
message = email.message_from_string(content)
dateheader = message.get('Date')
# parsedate_tz returns a 10-tuple that can be passed to mktime_tz;
# 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 = email.utils.parsedate_tz(dateheader)
if datetuple is None:
#could not determine the date, use the local time.
rtime = emailutil.get_message_date(content)
if rtime == None:
return None
#make it a real struct_time, so we have named attributes
datetuple = time.localtime(email.utils.mktime_tz(datetuple))
else:
#rtime is set, use that instead
datetuple = time.localtime(rtime)
datetuple = time.localtime(rtime)
try:
# Check for invalid dates