Skip to content

Commit

Permalink
Add no-delete-local to avoid remote->local delete synchronization.
Browse files Browse the repository at this point in the history
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
  • Loading branch information
ezyang committed Aug 31, 2012
1 parent 6c85a45 commit 266c88f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
12 changes: 12 additions & 0 deletions offlineimap.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions offlineimap/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,15 +435,15 @@ 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())

# 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())
Expand Down
29 changes: 20 additions & 9 deletions offlineimap/folder/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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])
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 266c88f

Please sign in to comment.