[PATCH v4 2/2] True 1-way sync (backup)

Sebastian Spaeth Sebastian at SSpaeth.de
Sun May 1 18:18:29 UTC 2011


This commit enables true 1-way syncing between repositories. This has
often been demanded for backup purposes when you do not want to cause
accidental modifications of your backup that would be propagated to the
other side.

This has been implemented by allowing to configure a Repository as
'readonly' to forbid any modification on it.

'readonly' applies to all the type of repositories.

Signed-off-by: Sebastian Spaeth <Sebastian at SSpaeth.de>
---
The change to v3 is the improved commit message, an added space after a
comma and changing the debug type from "imap" to "" as was requested by
Nicolas, the changes are really minor. I can send an interpatch diff
though.

 Changelog.draft.rst     |    5 +++++
 offlineimap.conf        |   25 ++++++++++++++++---------
 offlineimap/accounts.py |   24 +++++++++++++++++-------
 3 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/Changelog.draft.rst b/Changelog.draft.rst
index 0a85888..883b9a6 100644
--- a/Changelog.draft.rst
+++ b/Changelog.draft.rst
@@ -13,6 +13,11 @@ others.
 New Features
 ------------
 
+* Enable 1-way synchronization by settting a [Repository ...] to
+  readonly = True. When e.g. using offlineimap for backup purposes you
+  can thus make sure that no changes in your backup trickle back into
+  the main IMAP server.
+
 Changes
 -------
 
diff --git a/offlineimap.conf b/offlineimap.conf
index 7018090..f8506b2 100644
--- a/offlineimap.conf
+++ b/offlineimap.conf
@@ -1,6 +1,5 @@
 # Sample configuration file
-# Copyright (C) 2002-2005 John Goerzen
-# <jgoerzen at complete.org>
+# Copyright (C) 2002-2011 John Goerzen & contributors
 #
 #    This program is free software; you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -67,13 +66,14 @@ maxsyncaccounts = 1
 
 ui = Blinkenlights
 
-# If you try to synchronize messages to a read-only folder,
-# OfflineIMAP will generate a warning.  If you want to suppress these
-# warnings, set ignore-readonly to yes.  Read-only IMAP folders allow
-# reading but not modification, so if you try to change messages in
-# the local copy of such a folder, the IMAP server will prevent
-# OfflineIMAP from propagating those changes to the IMAP server.
-
+# If you try to synchronize messages to a folder which the IMAP server
+# considers read-only, OfflineIMAP will generate a warning.  If you want
+# to suppress these warnings, set ignore-readonly to yes.  Read-only
+# IMAP folders allow reading but not modification, so if you try to
+# change messages in the local copy of such a folder, the IMAP server
+# will prevent OfflineIMAP from propagating those changes to the IMAP
+# server.  Note that ignore-readonly is unrelated to the "readonly"
+# setting which prevents a repository from being modified at all.
 ignore-readonly = no
 
 ########## Advanced settings
@@ -469,6 +469,11 @@ subscribedonly = no
 #
 # foldersort = lambda x, y: -cmp(x, y)
 
+# Enable 1-way synchronization. When setting 'readonly' to True, this
+# repository will not be modified during synchronization. Use to
+# e.g. backup an IMAP server. The readonly setting can be applied to any
+# type of Repository (Maildir, Imap, etc).
+readonly = False
 
 [Repository GmailExample]
 
@@ -509,3 +514,5 @@ realdelete = no
 #
 # spamfolder = [Google Mail]/Spam
 
+# Enable 1-way synchronization. See above for explanation.
+readonly = False
diff --git a/offlineimap/accounts.py b/offlineimap/accounts.py
index 7edfa37..ac75ec8 100644
--- a/offlineimap/accounts.py
+++ b/offlineimap/accounts.py
@@ -242,8 +242,10 @@ class SyncableAccount(Account):
             remoterepos = self.remoterepos
             localrepos = self.localrepos
             statusrepos = self.statusrepos
-            self.ui.syncfolders(remoterepos, localrepos)
-            remoterepos.syncfoldersto(localrepos, [statusrepos])
+            # replicate the folderstructure from REMOTE to LOCAL
+            if not localrepos.getconf('readonly', False):
+                self.ui.syncfolders(remoterepos, localrepos)
+                remoterepos.syncfoldersto(localrepos, [statusrepos])
 
             siglistener.addfolders(remoterepos.getfolders(), bool(self.refreshperiod), quick)
 
@@ -349,12 +351,20 @@ def syncfolder(accountname, remoterepos, remotefolder, localrepos,
                              remotefolder.getmessagecount())
 
         # Synchronize remote changes.
-        ui.syncingmessages(remoterepos, remotefolder, localrepos, localfolder)
-        remotefolder.syncmessagesto(localfolder, statusfolder)
+        if not localrepos.getconf('readonly', False):
+            ui.syncingmessages(remoterepos, remotefolder, localrepos, localfolder)
+            remotefolder.syncmessagesto(localfolder, statusfolder)
+        else:
+            ui.debug('imap', "Not syncing to read-only repository '%s'" \
+                         % localrepos.getname())
+        
         # Synchronize local changes
-        ui.syncingmessages(localrepos, localfolder, remoterepos, remotefolder)
-        localfolder.syncmessagesto(remotefolder, statusfolder)
-
+        if not remoterepos.getconf('readonly', False):
+            ui.syncingmessages(localrepos, localfolder, remoterepos, remotefolder)
+            localfolder.syncmessagesto(remotefolder, statusfolder)
+        else:
+            ui.debug('', "Not syncing to read-only repository '%s'" \
+                         % remoterepos.getname())
 
         statusfolder.save()
         localrepos.restore_atime()
-- 
1.7.4.1




More information about the OfflineIMAP-project mailing list