From 6995eeb92e20b46e8f2d8b984d9d6ffbc4e2b875 Mon Sep 17 00:00:00 2001 From: Vladimir Marek Date: Tue, 12 Jul 2011 09:34:02 +0200 Subject: [PATCH] Support maildir for windows That makes OfflineIMAP to use exclamation mark (!) instead of colon for storing messages. Such files can be written to windows partitions. But you will probably loose compatibility with other programs trying to read the same Maildir. Signed-off-by: Vladimir Marek Reviewed-by: Sebastian Spaeth Signed-off-by: Nicolas Sebrecht --- docs/MANUAL.rst | 21 +++++++++++++++++++++ offlineimap.conf | 10 ++++++++++ offlineimap/folder/Maildir.py | 21 ++++++++++++++++----- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/docs/MANUAL.rst b/docs/MANUAL.rst index 26f31a6..e6a32e2 100644 --- a/docs/MANUAL.rst +++ b/docs/MANUAL.rst @@ -300,5 +300,26 @@ KNOWN BUGS * IDLE may only work "once" per refresh. If you encounter this bug, please send a report to the list! +* Maildir support in Windows drive + Maildir uses colon caracter (:) in message file names. Colon is however + forbidden character in windows drives. There are several workarounds for + that situation: + + * Use "maildir-windows-compatible = yes" account OfflineIMAP configuration. + - That makes OfflineIMAP to use exclamation mark (!) instead of colon for + storing messages. Such files can be written to windows partitions. But + you will probably loose compatibility with other programs trying to + read the same Maildir. + - Exclamation mark was choosed because of the note in + http://docs.python.org/library/mailbox.html + - If you have some messages already stored without this option, you will + have to re-sync them again + + * Enable file name character translation in windows registry (not tested) + - http://support.microsoft.com/kb/289627 + + * Use cygwin managed mount (not tested) + - not available anymore since cygwin 1.7 + SEE ALSO ======== diff --git a/offlineimap.conf b/offlineimap.conf index 9329c66..2a4b1a2 100644 --- a/offlineimap.conf +++ b/offlineimap.conf @@ -239,6 +239,16 @@ remoterepository = RemoteExample # maxage = 3 + +# Maildir format uses colon (:) separator between uniq name and info. +# Unfortunatelly colon is not allowed character in windows file name. If you +# enable maildir-windows-compatible option, offlineimap will be able to store +# messages on windows drive, but you will probably loose compatibility with +# other programs working with the maildir + +# maildir-windows-compatible = no + + [Repository LocalExample] # This is one of the two repositories that you'll work with given the diff --git a/offlineimap/folder/Maildir.py b/offlineimap/folder/Maildir.py index b576507..3b53156 100644 --- a/offlineimap/folder/Maildir.py +++ b/offlineimap/folder/Maildir.py @@ -31,7 +31,6 @@ except ImportError: from offlineimap import OfflineImapError uidmatchre = re.compile(',U=(\d+)') -flagmatchre = re.compile(':.*2,([A-Z]+)') timestampmatchre = re.compile('(\d+)'); timeseq = 0 @@ -63,6 +62,17 @@ class MaildirFolder(BaseFolder): self.messagelist = None self.repository = repository self.accountname = accountname + + self.wincompatible = self.config.getdefaultboolean( + "Account "+self.accountname, "maildir-windows-compatible", False) + + if self.wincompatible == False: + self.infosep = ':' + else: + self.infosep = '!' + + self.flagmatchre = re.compile(self.infosep + '.*2,([A-Z]+)') + BaseFolder.__init__(self) #self.ui is set in BaseFolder.init() # Cache the full folder path, as we use getfullname() very often @@ -156,7 +166,7 @@ class MaildirFolder(BaseFolder): nouidcounter -= 1 else: uid = long(uidmatch.group(1)) - flagmatch = flagmatchre.search(messagename) + flagmatch = self.flagmatchre.search(messagename) flags = [] if flagmatch: flags = [x for x in flagmatch.group(1)] @@ -271,11 +281,12 @@ class MaildirFolder(BaseFolder): dir_prefix = 'cur' else: dir_prefix = 'new' - infostr = ':' - infomatch = re.search('(:.*)$', newname) + + infostr = self.infosep + infomatch = re.search('(' + self.infosep + '.*)$', newname) if infomatch: # If the info string is present.. infostr = infomatch.group(1) - newname = newname.split(':')[0] # Strip off the info string. + newname = newname.split(self.infosep)[0] # Strip off the info string. infostr = re.sub('2,[A-Z]*', '', infostr) flags.sort() infostr += '2,' + ''.join(flags)