diff MoinMoin/action/SyncPages.py @ 1385:8bf6e48c6236

Added rollback and exception logging to SyncPages.
author Alexander Schremmer <alex AT alexanderweb DOT de>
date Sun, 20 Aug 2006 18:37:26 +0200
parents dfed953d5e9f
children 0559fa036536
line wrap: on
line diff
--- a/MoinMoin/action/SyncPages.py	Sun Aug 20 17:29:00 2006 +0200
+++ b/MoinMoin/action/SyncPages.py	Sun Aug 20 18:37:26 2006 +0200
@@ -24,7 +24,7 @@
 from MoinMoin.PageEditor import PageEditor, conflict_markers
 from MoinMoin.Page import Page
 from MoinMoin.wikidicts import Dict, Group
-from MoinMoin.wikisync import TagStore, UnsupportedWikiException, SyncPage
+from MoinMoin.wikisync import TagStore, UnsupportedWikiException, SyncPage, NotAllowedException
 from MoinMoin.wikisync import MoinLocalWiki, MoinRemoteWiki, UP, DOWN, BOTH, MIMETYPE_MOIN
 from MoinMoin.util.bdiff import decompress, patch, compress, textdiff
 from MoinMoin.util import diff3
@@ -136,15 +136,20 @@
 
             if not remote.valid:
                 raise ActionStatus(_("The ''remoteWiki'' is unknown."))
-
-            self.sync(params, local, remote)
         except ActionStatus, e:
             msg = u'<p class="error">%s</p>\n' % (e.args[0], )
-        else:
-            msg = u"%s" % (_("Syncronisation finished. Look below for the status messages."), )
 
-        self.page.saveText(self.page.get_raw_body() + "\n\n" + self.generate_log_table(), 0)
-        # XXX release readlock on self.page
+        try:
+            try:
+                self.sync(params, local, remote)
+            except Exception, e:
+                self.log_status(self.ERROR, _("A severe error occured:"), raw_suffix=repr(e))
+                raise
+            else:
+                msg = u"%s" % (_("Syncronisation finished. Look below for the status messages."), )
+        finally:
+            self.page.saveText(self.page.get_raw_body() + "\n\n" + self.generate_log_table(), 0)
+            # XXX release readlock on self.page
 
         self.page.send_page(self.request, msg=msg)
 
@@ -335,21 +340,37 @@
 
             # XXX upgrade to write lock
             try:
+                local_change_done = True
                 current_page.saveText(merged_text, sp.local_rev, comment=comment) # YYY direct access
             except PageEditor.Unchanged:
-                pass
+                local_change_done = False
             except PageEditor.EditConflict:
+                local_change_done = False
                 assert False, "You stumbled on a problem with the current storage system - I cannot lock pages"
 
             new_local_rev = current_page.get_real_rev() # YYY direct access
 
-            if direction == BOTH:
-                try:
-                    very_current_remote_rev = remote.merge_diff(sp.remote_name, compress(diff), new_local_rev, current_remote_rev, current_remote_rev, local_full_iwid, sp.name)
-                except Exception, e:
-                    raise # XXX rollback locally and do not tag locally
-            else:
-                very_current_remote_rev = current_remote_rev
+            def rollback_local_change(): # YYY direct local access
+                rev = new_local_rev - 1
+                revstr = '%08d' % rev
+                oldpg = Page(self.request, sp.local_name, rev=rev)
+                pg = PageEditor(self.request, sp.local_name)
+                savemsg = pg.saveText(oldpg.get_raw_body(), 0, comment=u"Wikisync rollback", extra=revstr, action="SAVE/REVERT")
+
+            try:
+                if direction == BOTH:
+                    try:
+                        very_current_remote_rev = remote.merge_diff(sp.remote_name, compress(diff), new_local_rev, current_remote_rev, current_remote_rev, local_full_iwid, sp.name)
+                    except NotAllowedException:
+                        self.log_status(ActionClass.ERROR, _("Page could not be merged because you are not allowed to modify the page in the remote wiki."))
+                        return
+                else:
+                    very_current_remote_rev = current_remote_rev
+
+                local_change_done = False # changes are committed remotely, all is fine
+            finally:
+                if local_change_done:
+                    rollback_local_change()
 
             tags.add(remote_wiki=remote_full_iwid, remote_rev=very_current_remote_rev, current_rev=new_local_rev, direction=direction, normalised_name=sp.name)