no-delete-local patch for offlineimap
Petr Fischer
petr.fischer at me.com
Mon May 25 20:45:54 BST 2015
OK. I exported the patch from github commit for your review.
I'm not sure if it's a patch against the latest version of your source, but it's a few lines of code only.
Thanks! Petr Fischer
> On Thu, May 21, 2015 at 07:14:38PM +0200, Petr Fischer wrote:
> > Hello!
> >
> > is possible to add this useful patch for "no-delete-local" option to the official offlineimap release?
> > It's usefull and simple. Users of offlineimap sometimes want this feature (found on internet, forums etc.).
> >
> > This is not my patch, it's patch from some github fork.
> >
> > https://github.com/OfflineIMAP/offlineimap/commit/266c88f7a1b041ba169e0c0cab767bf412c23672
>
> I'm sorry I was not clear. The idea is to send the patch by mail so we
> can discuss the content here.
>
> --
> Nicolas Sebrecht
-------------- next part --------------
>From 266c88f7a1b041ba169e0c0cab767bf412c23672 Mon Sep 17 00:00:00 2001
From: "Edward Z. Yang" <ezyang at mit.edu>
Date: Fri, 31 Aug 2012 16:51:33 -0400
Subject: [PATCH] Add no-delete-local to avoid remote->local delete
synchronization.
Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
---
offlineimap.conf | 12 ++++++++++++
offlineimap/accounts.py | 4 ++--
offlineimap/folder/Base.py | 29 ++++++++++++++++++++---------
3 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/offlineimap.conf b/offlineimap.conf
index fccceab..51a196a 100644
--- a/offlineimap.conf
+++ b/offlineimap.conf
@@ -252,6 +252,18 @@ remoterepository = RemoteExample
#maildir-windows-compatible = no
+# In many cases, your remote repository is intended to contain a subset
+# of the messages your local repository, because the remote repository
+# has less disk space, etc. However, if you just remove messages from
+# the remote repository, OfflineIMAP will synchronize the changes back
+# and delete your local copies. If you set this to 'yes', OfflineIMAP
+# will never delete local files even if they disappear on the remote
+# side. Local to remote deletes are still synchronized. See also
+# maxage.
+#
+# no-delete-local = no
+
+
[Repository LocalExample]
# Each repository requires a "type" declaration. The types supported for
diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py
index 8b39c7e..4b4bd44 100644
--- a/offlineimap/accounts.py
+++ b/offlineimap/accounts.py
@@ -435,7 +435,7 @@ def syncfolder(account, remotefolder, quick):
# Synchronize remote changes.
if not localrepos.getconfboolean('readonly', False):
ui.syncingmessages(remoterepos, remotefolder, localrepos, localfolder)
- remotefolder.syncmessagesto(localfolder, statusfolder)
+ remotefolder.syncmessagesto(localfolder, statusfolder, False)
else:
ui.debug('imap', "Not syncing to read-only repository '%s'" \
% localrepos.getname())
@@ -443,7 +443,7 @@ def syncfolder(account, remotefolder, quick):
# Synchronize local changes
if not remoterepos.getconfboolean('readonly', False):
ui.syncingmessages(localrepos, localfolder, remoterepos, remotefolder)
- localfolder.syncmessagesto(remotefolder, statusfolder)
+ localfolder.syncmessagesto(remotefolder, statusfolder, True)
else:
ui.debug('', "Not syncing to read-only repository '%s'" \
% remoterepos.getname())
diff --git a/offlineimap/folder/Base.py b/offlineimap/folder/Base.py
index 6f6f364..d5c5425 100644
--- a/offlineimap/folder/Base.py
+++ b/offlineimap/folder/Base.py
@@ -294,7 +294,7 @@ def deletemessages(self, uidlist):
for uid in uidlist:
self.deletemessage(uid)
- def copymessageto(self, uid, dstfolder, statusfolder, register = 1):
+ def copymessageto(self, uid, dstfolder, statusfolder, always_sync_deletes, register = 1):
"""Copies a message from self to dst if needed, updating the status
Note that this function does not check against dryrun settings,
@@ -366,7 +366,7 @@ def copymessageto(self, uid, dstfolder, statusfolder, register = 1):
exc_info()[2]))
raise #raise on unknown errors, so we can fix those
- def syncmessagesto_copy(self, dstfolder, statusfolder):
+ def syncmessagesto_copy(self, dstfolder, statusfolder, always_sync_deletes):
"""Pass1: Copy locally existing messages not on the other side
This will copy messages to dstfolder that exist locally but are
@@ -401,16 +401,16 @@ def syncmessagesto_copy(self, dstfolder, statusfolder):
self.getcopyinstancelimit(),
target = self.copymessageto,
name = "Copy message from %s:%s" % (self.repository, self),
- args = (uid, dstfolder, statusfolder))
+ args = (uid, dstfolder, statusfolder, always_sync_deletes))
thread.start()
threads.append(thread)
else:
- self.copymessageto(uid, dstfolder, statusfolder,
+ self.copymessageto(uid, dstfolder, statusfolder, always_sync_deletes,
register = 0)
for thread in threads:
thread.join()
- def syncmessagesto_delete(self, dstfolder, statusfolder):
+ def syncmessagesto_delete(self, dstfolder, statusfolder, always_sync_deletes):
"""Pass 2: Remove locally deleted messages on dst
Get all UIDS in statusfolder but not self. These are messages
@@ -419,8 +419,19 @@ def syncmessagesto_delete(self, dstfolder, statusfolder):
This function checks and protects us from action in ryrun mode.
"""
+ # This is functionally equivalent to having an empty deletelist
+ # in the case of not always_sync_deletes and no-delete-local turned on; the
+ # only difference is that in this regime we eagerly clear out
+ # "stale" entries from statusfolder, i.e. ones that are not
+ # present in the local or destination folder, whereas if we were
+ # to skip this the entries hang around until a not always_sync_deletes
+ # run.
+ sync_deletes = always_sync_deletes or not self.config.getdefaultboolean("Account " + self.accountname, "no-delete-local", False)
+ print sync_deletes
+ import sys
+ sys.exit()
deletelist = filter(lambda uid: uid>=0 \
- and not self.uidexists(uid),
+ and not self.uidexists(uid) and (sync_deletes or not dstfolder.uidexists(uid)),
statusfolder.getmessageuidlist())
if len(deletelist):
self.ui.deletingmessages(deletelist, [dstfolder])
@@ -431,7 +442,7 @@ def syncmessagesto_delete(self, dstfolder, statusfolder):
for folder in [statusfolder, dstfolder]:
folder.deletemessages(deletelist)
- def syncmessagesto_flags(self, dstfolder, statusfolder):
+ def syncmessagesto_flags(self, dstfolder, statusfolder, always_sync_deletes):
"""Pass 3: Flag synchronization
Compare flag mismatches in self with those in statusfolder. If
@@ -485,7 +496,7 @@ def syncmessagesto_flags(self, dstfolder, statusfolder):
dstfolder.deletemessagesflags(uids, set(flag))
statusfolder.deletemessagesflags(uids, set(flag))
- def syncmessagesto(self, dstfolder, statusfolder):
+ def syncmessagesto(self, dstfolder, statusfolder, always_sync_deletes):
"""Syncs messages in this folder to the destination dstfolder.
This is the high level entry for syncing messages in one direction.
@@ -523,7 +534,7 @@ def syncmessagesto(self, dstfolder, statusfolder):
if offlineimap.accounts.Account.abort_NOW_signal.is_set():
break
try:
- action(dstfolder, statusfolder)
+ action(dstfolder, statusfolder, always_sync_deletes)
except (KeyboardInterrupt):
raise
except OfflineImapError as e:
More information about the OfflineIMAP-project
mailing list