changeset 1267:eb9e5e21b0e5

Implemented the DOWN direction, refactored direction handling. The synctags of older syncs are invalid now, you have to delete them.
author Alexander Schremmer <alex AT alexanderweb DOT de>
date Sun, 13 Aug 2006 16:05:28 +0200
parents ff08338e67fe
children 7ef804645070
files MoinMoin/action/SyncPages.py MoinMoin/wikisync.py MoinMoin/xmlrpc/__init__.py docs/CHANGES.aschremmer
diffstat 4 files changed, 43 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/SyncPages.py	Sun Aug 13 13:25:30 2006 +0200
+++ b/MoinMoin/action/SyncPages.py	Sun Aug 13 16:05:28 2006 +0200
@@ -24,13 +24,13 @@
 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, MoinLocalWiki, MoinRemoteWiki
+from MoinMoin.wikisync import (TagStore, UnsupportedWikiException, SyncPage,
+                               MoinLocalWiki, MoinRemoteWiki, UP, DOWN, BOTH)
 from MoinMoin.util.bdiff import decompress, patch, compress, textdiff
 from MoinMoin.util import diff3
 
 
-# directions
-UP, DOWN, BOTH = range(3)
+# map sync directions
 directions_map = {"up": UP, "down": DOWN, "both": BOTH}
 
 
@@ -45,6 +45,7 @@
         self.pagename = pagename
         self.page = Page(request, pagename)
         self.status = []
+        request.flush()
 
     def log_status(self, level, message):
         """ Appends the message with a given importance level to the internal log. """
@@ -70,7 +71,7 @@
         if options["groupList"] is not None:
             options["groupList"] = unpackLine(options["groupList"], ",")
 
-        options["direction"] = directions_map.get(options["direction"], BOTH)
+        options["direction"] = directions_map.get(options["direction"].lower(), BOTH)
 
         return options
 
@@ -170,7 +171,11 @@
             current_rev = current_page.get_real_rev()
 
             tags = TagStore(current_page)
-            matching_tags = tags.fetch(iwid_full=remote.iwid_full)
+            if direction == BOTH:
+                match_direction = direction
+            else:
+                match_direction = None
+            matching_tags = tags.fetch(iwid_full=remote.iwid_full,direction=match_direction)
             matching_tags.sort()
             #print "------ TAGS: " + repr(matching_tags) + repr(tags.tags)
 
@@ -188,6 +193,12 @@
 
             self.log_status(ActionClass.INFO, _("Synchronising page %(pagename)s with remote page %(remotepagename)s ...") % {"pagename": local_pagename, "remotepagename": rp.remote_name})
 
+            if direction == DOWN:
+                remote_rev = None # always fetch the full page, ignore remote conflict check
+                patch_base_contents = ""
+            else:
+                patch_base_contents = old_contents
+
             if remote_rev != rp.remote_rev:
                 diff_result = remote.get_diff(rp.remote_name, remote_rev, None) # XXX might raise ALREADY_CURRENT
                 is_remote_conflict = diff_result["conflict"]
@@ -206,20 +217,17 @@
                 self.log_status(ActionClass.WARN, _("Skipped page %(pagename)s because of a locally or remotely unresolved conflict.") % {"pagename": local_pagename})
                 continue
 
-            if remote_rev is None: # set the remote_rev for the case without any tags
+            if remote_rev is None and direction == BOTH:
                 self.log_status(ActionClass.INFO, _("This is the first synchronisation between this page and the remote wiki."))
-                remote_rev = current_remote_rev
 
-            old_contents_dec = old_contents.decode("utf-8")
             if diff is None:
-                new_contents = old_contents_dec
+                new_contents = old_contents.decode("utf-8")
             else:
-                new_contents = patch(old_contents, decompress(diff)).decode("utf-8")
-            old_contents = old_contents_dec
+                new_contents = patch(patch_base_contents, decompress(diff)).decode("utf-8")
 
             # here, the actual merge happens
-            print "Merging %r, %r and %r" % (old_contents, new_contents, current_page.get_raw_body())
-            verynewtext = diff3.text_merge(old_contents, new_contents, current_page.get_raw_body(), 2, *conflict_markers)
+            print "Merging %r, %r and %r" % (old_contents.decode("utf-8"), new_contents, current_page.get_raw_body())
+            verynewtext = diff3.text_merge(old_contents.decode("utf-8"), new_contents, current_page.get_raw_body(), 2, *conflict_markers)
 
             local_full_iwid = packLine([local.get_iwid(), local.get_interwiki_name()])
             remote_full_iwid = packLine([remote.get_iwid(), remote.get_interwiki_name()])
@@ -239,12 +247,15 @@
 
             new_local_rev = current_page.get_real_rev()
 
-            try:
-                very_current_remote_rev = remote.merge_diff(rp.remote_name, compress(diff), new_local_rev, current_remote_rev, current_remote_rev, local_full_iwid)
-            except Exception, e:
-                raise # XXX rollback locally
+            if direction == BOTH:
+                try:
+                    very_current_remote_rev = remote.merge_diff(rp.remote_name, compress(diff), new_local_rev, current_remote_rev, current_remote_rev, local_full_iwid)
+                except Exception, e:
+                    raise # XXX rollback locally and do not tag locally
             else:
-                tags.add(remote_wiki=remote_full_iwid, remote_rev=very_current_remote_rev, current_rev=new_local_rev)
+                very_current_remote_rev = current_remote_rev
+
+            tags.add(remote_wiki=remote_full_iwid, remote_rev=very_current_remote_rev, current_rev=new_local_rev, direction=direction)
 
             if not wikiutil.containsConflictMarker(verynewtext):
                 self.log_status(ActionClass.INFO, _("Page successfully merged."))
--- a/MoinMoin/wikisync.py	Sun Aug 13 13:25:30 2006 +0200
+++ b/MoinMoin/wikisync.py	Sun Aug 13 16:05:28 2006 +0200
@@ -21,6 +21,10 @@
 from MoinMoin.packages import unpackLine, packLine
 
 
+# sync directions
+UP, DOWN, BOTH = range(3)
+
+
 def normalise_pagename(page_name, prefix):
     """ Checks if the page_name starts with the prefix.
         Returns None if it does not, otherwise strips the prefix.
@@ -299,17 +303,19 @@
 class Tag(object):
     """ This class is used to store information about merging state. """
     
-    def __init__(self, remote_wiki, remote_rev, current_rev):
+    def __init__(self, remote_wiki, remote_rev, current_rev, direction):
         """ Creates a new Tag.
         
         @param remote_wiki: The identifier of the remote wiki.
         @param remote_rev: The revision number on the remote end.
         @param current_rev: The related local revision.
+        @param direction: The direction of the sync, encoded as an integer.
         """
         assert isinstance(remote_wiki, str) and isinstance(remote_rev, int) and isinstance(current_rev, int)
         self.remote_wiki = remote_wiki
         self.remote_rev = remote_rev
         self.current_rev = current_rev
+        self.direction = direction
 
     def __repr__(self):
         return u"<Tag remote_wiki=%r remote_rev=%r current_rev=%r>" % (self.remote_wiki, self.remote_rev, self.current_rev)
@@ -405,13 +411,14 @@
         self.tags = []
         self.commit()
 
-    def fetch(self, iwid_full):
+    def fetch(self, iwid_full, direction=None):
         iwid_full = unpackLine(iwid_full)
         matching_tags = []
         for t in self.tags:
             t_iwid_full = unpackLine(t.remote_wiki)
             if ((t_iwid_full[0] == iwid_full[0]) # either match IWID or IW name
-                or (len(t_iwid_full) == 2 and len(iwid_full) == 2 and t_iwid_full[1] == iwid_full[1])):
+                or (len(t_iwid_full) == 2 and len(iwid_full) == 2 and t_iwid_full[1] == iwid_full[1])
+                ) and (direction is None or t.direction == direction):
                 matching_tags.append(t)
         return matching_tags
 
--- a/MoinMoin/xmlrpc/__init__.py	Sun Aug 13 13:25:30 2006 +0200
+++ b/MoinMoin/xmlrpc/__init__.py	Sun Aug 13 16:05:28 2006 +0200
@@ -580,6 +580,7 @@
     def xmlrpc_getDiff(self, pagename, from_rev, to_rev):
         """ Gets the binary difference between two page revisions. See MoinMoin:WikiSyncronisation. """
         from MoinMoin.util.bdiff import textdiff, compress
+        from MoinMoin.wikisync import BOTH
 
         pagename = self._instr(pagename)
 
@@ -694,7 +695,7 @@
         current_rev = currentpage.get_real_rev()
         
         tags = TagStore(currentpage)
-        tags.add(remote_wiki=interwiki_name, remote_rev=local_rev, current_rev=current_rev)
+        tags.add(remote_wiki=interwiki_name, remote_rev=local_rev, current_rev=current_rev, direction=BOTH)
 
         # XXX unlock page
 
--- a/docs/CHANGES.aschremmer	Sun Aug 13 13:25:30 2006 +0200
+++ b/docs/CHANGES.aschremmer	Sun Aug 13 16:05:28 2006 +0200
@@ -11,6 +11,7 @@
     * Test with prefixes
     * Reduce round-trip times by caching queries and using MultiCall objects.
     * Attach the status information to the job page.
+    * Show tags in an action=info view?
     * Implement a cross-site authentication system, i.e. mainly an
       identity storage.
     * Clean up trailing whitespace.
@@ -99,7 +100,7 @@
          XMLRPC functions to return Fault instances. Introduced a new diff3 mode that should reduce the
          conflicts. Fixed hard to track down bugs in SyncPages. Store full IWIDs and match by
          either of both components when searching for tags. Ignore underlay pages. Filter the remote page list by
-         the prefix and the pageList on the remote side.
+         the prefix and the pageList on the remote side. Finished the direction==DOWN mode.
 
 2006-07-18: the requested daily entry is missing here, see http://moinmoin.wikiwikiweb.de/GoogleSoc2006/BetterProgress
 2006-07-19: the requested daily entry is missing here, see http://moinmoin.wikiwikiweb.de/GoogleSoc2006/BetterProgress