From 89e530ff6e541dff23bb9b4a2f1ae1563832eb81 Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Wed, 6 Sep 2006 02:33:07 +0100 Subject: [PATCH] New restoreatime patch from Ben Kibbey From: Ben Kibbey Subject: Re: Removed restoratime from OfflineIMAP On Wed, May 03, 2006 at 10:08:35PM -0500, John Goerzen wrote: > Hi Ben, > > Thanks for your restoreatime patch. > > However, I have received this bug report: > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=365933 > > After looking at the problem, here's what's going on. > > The person is using IMAP as the local repository as well. > > You really need to move the atime save and restore code from accounts.py > into the repository/Maildir.py. Then, for any new call you add to the > Maildir repository (that will be called from outside Maildir.py), you > need to add a corresponding default function to repository/Base.py, and > also make sure that on folders (such as IMAP) where atime restoration > makes no sense, no error is generated. > > Let me know if that doesn't make sense to you. If you get it fixed, I'd > be happy to re-apply it to a future version of OfflineIMAP. > > -- John Goerzen > Attached is a new diff that should work though not really tested (v4.0.14). In repository/Base.py restore_atime() will call self.restore_folder_atimes() only if the folder type is Maildir. Let me know if it has any more problems. --- offlineimap/accounts.py | 3 +++ offlineimap/repository/Base.py | 12 ++++++++++++ offlineimap/repository/Maildir.py | 23 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py index b367de1..5478fe7 100644 --- a/offlineimap/accounts.py +++ b/offlineimap/accounts.py @@ -191,10 +191,12 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, if not localfolder.isuidvalidityok(): ui.validityproblem(localfolder, localfolder.getsaveduidvalidity(), localfolder.getuidvalidity()) + localrepos.restore_atime() return if not remotefolder.isuidvalidityok(): ui.validityproblem(remotefolder, remotefolder.getsaveduidvalidity(), remotefolder.getuidvalidity()) + localrepos.restore_atime() return else: localfolder.saveuidvalidity() @@ -230,4 +232,5 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos, ui.syncingmessages(localrepos, localfolder, statusrepos, statusfolder) localfolder.syncmessagesto(statusfolder) statusfolder.save() + localrepos.restore_atime() diff --git a/offlineimap/repository/Base.py b/offlineimap/repository/Base.py index 945183f..94bce09 100644 --- a/offlineimap/repository/Base.py +++ b/offlineimap/repository/Base.py @@ -51,6 +51,18 @@ class BaseRepository(CustomConfig.ConfigHelperMixin): if not os.path.exists(self.uiddir): os.mkdir(self.uiddir, 0700) + # The 'restoreatime' config parameter only applies to local Maildir + # mailboxes. + def restore_atime(self): + if self.config.get('Repository ' + self.name, 'type').strip() != \ + 'Maildir': + return + + if not self.config.has_option('Repository ' + self.name, 'restoreatime') or not self.config.getboolean('Repository ' + self.name, 'restoreatime'): + return + + return self.restore_folder_atimes() + def holdordropconnections(self): pass diff --git a/offlineimap/repository/Maildir.py b/offlineimap/repository/Maildir.py index fc92bc4..bb011d5 100644 --- a/offlineimap/repository/Maildir.py +++ b/offlineimap/repository/Maildir.py @@ -21,6 +21,7 @@ from offlineimap import folder, imaputil from offlineimap.ui import UIBase from mailbox import Maildir import os +from stat import * class MaildirRepository(BaseRepository): def __init__(self, reposname, account): @@ -32,6 +33,24 @@ class MaildirRepository(BaseRepository): self.folders = None self.ui = UIBase.getglobalui() self.debug("MaildirRepository initialized, sep is " + repr(self.getsep())) + self.folder_atimes = [] + + def _append_folder_atimes(self, foldername): + p = os.path.join(self.root, foldername) + new = os.path.join(p, 'new') + cur = os.path.join(p, 'cur') + f = p, os.stat(new)[ST_ATIME], os.stat(cur)[ST_ATIME] + self.folder_atimes.append(f) + + def restore_folder_atimes(self): + if not self.folder_atimes: + return + + for f in self.folder_atimes: + t = f[1], os.stat(os.path.join(f[0], 'new'))[ST_MTIME] + os.utime(os.path.join(f[0], 'new'), t) + t = f[2], os.stat(os.path.join(f[0], 'cur'))[ST_MTIME] + os.utime(os.path.join(f[0], 'cur'), t) def getlocalroot(self): return os.path.expanduser(self.getconf('localfolders')) @@ -86,6 +105,8 @@ class MaildirRepository(BaseRepository): self.ui.warn("NOT YET IMPLEMENTED: DELETE FOLDER %s" % foldername) def getfolder(self, foldername): + if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): + self._append_folder_atimes(foldername) return folder.Maildir.MaildirFolder(self.root, foldername, self.getsep(), self, self.accountname) @@ -130,6 +151,8 @@ class MaildirRepository(BaseRepository): self.debug(" foldername = %s" % foldername) + if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): + self._append_folder_atimes(foldername) retval.append(folder.Maildir.MaildirFolder(self.root, foldername, self.getsep(), self, self.accountname)) if self.getsep() == '/' and dirname != '.':