From 5d5ad62fa788ed63f15ea61fafa6de28de407584 Mon Sep 17 00:00:00 2001 From: Nicolas Sebrecht Date: Thu, 18 May 2017 10:10:26 +0200 Subject: [PATCH] mbnames: don't duplicate entries in autorefresh mode mbnames is initialized and written once in the run from OfflineImap.__sync(). However, the in-memory instance is fed with data at sync time for each folder and the intermediate files are written as soon as all the folders are synced for the account. All of this is done inside the SyncableAccount.__sync() method while the syncrunner is looping on this. This means that we duplicate entries for mbnames in each loop (most likely when autorefresh is enabled). It is wrong to have duplicates in mbnames for each account. Ignore duplicates when adding data in the mbnames intermediate files. Github-ref: https://github.com/OfflineIMAP/offlineimap/issues/467 Reported-and-tested-by: Shin Kojima Signed-off-by: Nicolas Sebrecht --- offlineimap/accounts.py | 3 +++ offlineimap/mbnames.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py index 0e5d8ed..c06ae3d 100644 --- a/offlineimap/accounts.py +++ b/offlineimap/accounts.py @@ -309,6 +309,9 @@ class SyncableAccount(Account): remotefolder.getvisiblename(). replace(self.remoterepos.getsep(), self.localrepos.getsep())) + + # The syncrunner will loop on this method. This means it is called more than + # once during the run. def __sync(self): """Synchronize the account once, then return. diff --git a/offlineimap/mbnames.py b/offlineimap/mbnames.py index 4cd538f..ca5fe1f 100644 --- a/offlineimap/mbnames.py +++ b/offlineimap/mbnames.py @@ -32,6 +32,7 @@ _mbLock = Lock() _mbnames = None +# Called at sync time for each folder. def add(accountname, folder_root, foldername): global _mbnames if _mbnames.is_enabled() is not True: @@ -41,12 +42,14 @@ def add(accountname, folder_root, foldername): _mbnames.addAccountFolder(accountname, folder_root, foldername) +# Called once. def init(conf, ui, dry_run): global _mbnames if _mbnames is None: _mbnames = _Mbnames(conf, ui, dry_run) +# Called once. def prune(accounts): global _mbnames if _mbnames.is_enabled() is True: @@ -55,6 +58,7 @@ def prune(accounts): _mbnames.pruneAll() +# Called once. def write(): """Write the mbnames file.""" @@ -66,6 +70,7 @@ def write(): _mbnames.write() +# Called as soon as all the folders are synced for the account. def writeIntermediateFile(accountname): """Write intermediate mbnames file.""" @@ -93,7 +98,8 @@ class _IntermediateMbnames(object): self._dryrun = dry_run def add(self, foldername): - self._foldernames.append(foldername) + if foldername not in self._foldernames: + self._foldernames.append(foldername) def get_folder_root(self): return self._folder_root