changeset 1136:4ba6da7e23a4

Started implementing the merging process. Not working yet.
author Alexander Schremmer <alex AT alexanderweb DOT de>
date Fri, 04 Aug 2006 22:12:30 +0200
parents bf5f8afacf59
children 484b34dd3c23
files MoinMoin/action/SyncPages.py MoinMoin/wikisync.py docs/CHANGES.aschremmer
diffstat 3 files changed, 63 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/SyncPages.py	Fri Aug 04 21:34:36 2006 +0200
+++ b/MoinMoin/action/SyncPages.py	Fri Aug 04 22:12:30 2006 +0200
@@ -26,6 +26,8 @@
 from MoinMoin.PageEditor import PageEditor
 from MoinMoin.Page import Page
 from MoinMoin.wikidicts import Dict, Group
+from MoinMoin.wikisync import TagStore
+from MoinMoin.util.bdiff import decompress, patch
 
 # directions
 UP, DOWN, BOTH = range(3)
@@ -46,7 +48,7 @@
 
 class UnsupportedWikiException(Exception): pass
 
-# Move these classes to MoinMoin.wikisync
+# XXX Move these classes to MoinMoin.wikisync
 class SyncPage(object):
     """ This class represents a page in (another) wiki. """
     def __init__(self, name, local_rev=None, remote_rev=None, local_name=None, remote_name=None):
@@ -172,6 +174,9 @@
     def createConnection(self):
         return xmlrpclib.ServerProxy(self.xmlrpc_url, allow_none=True, verbose=True)
 
+    def get_diff(self, pagename, from_rev, to_rev):
+        return str(self.connection.getDiff(pagename, from_rev, to_rev))
+
     # Methods implementing the RemoteWiki interface
     def get_interwiki_name(self):
         return self.connection.interwikiName()[0]
@@ -300,9 +305,9 @@
     
     def sync(self, params, local, remote):
         """ This method does the syncronisation work. """
-        
+
+        l_pages = local.get_pages()
         r_pages = remote.get_pages()
-        l_pages = local.get_pages()
 
         if params["groupList"]:
             pages_from_groupList = set(local.getGroupItems(params["groupList"]))
@@ -321,14 +326,39 @@
         remote_but_not_local = list(SyncPage.iter_remote_only(m_pages))
         local_but_not_remote = list(SyncPage.iter_local_only(m_pages))
         
-        # some initial test code
-        r_new_pages = u", ".join([unicode(x) for x in remote_but_not_local])
-        l_new_pages = u", ".join([unicode(x) for x in local_but_not_remote])
-        raise ActionStatus("These pages are in the remote wiki, but not local: " + wikiutil.escape(r_new_pages) + "<br>These pages are in the local wiki, but not in the remote one: " + wikiutil.escape(l_new_pages))
+        # some initial test code (XXX remove)
+        #r_new_pages = u", ".join([unicode(x) for x in remote_but_not_local])
+        #l_new_pages = u", ".join([unicode(x) for x in local_but_not_remote])
+        #raise ActionStatus("These pages are in the remote wiki, but not local: " + wikiutil.escape(r_new_pages) + "<br>These pages are in the local wiki, but not in the remote one: " + wikiutil.escape(l_new_pages))
         #if params["direction"] in (DOWN, BOTH):
         #    for rp in remote_but_not_local:
-                # XXX add locking, acquire read-lock on rp
-                
+
+        # let's do the simple case first, can be refactored later to match all cases
+        for rp in on_both_sides:
+            # XXX add locking, acquire read-lock on rp
+
+            local_pagename = rp.local_pagename
+
+            tags = TagStore(Page(self.request, local_pagename))
+            matching_tags = tags.fetch(iwid_full=remote.iwid_full)
+            matching_tags.sort()
+
+            if not matching_tags:
+                remote_rev = None
+                local_rev = rp.local_rev # merge against the newest version
+                old_contents = ""
+            else:
+                newest_tag = matching_tags[-1]
+                local_rev = newest_tag.current_rev
+                remote_rev = newest_tag.remote_rev
+                old_contents = local_page.get_raw_body_str()
+
+            local_page = Page(self.request, local_pagename, rev=local_rev)
+
+            diff = remote.get_diff(rp.remote_pagename, remote_rev, None)
+            new_contents = patch(old_contents, decompress(diff)).decode("utf-8")
+            # XXX this is not finished yet
+            
 
 
 def execute(pagename, request):
--- a/MoinMoin/wikisync.py	Fri Aug 04 21:34:36 2006 +0200
+++ b/MoinMoin/wikisync.py	Fri Aug 04 22:12:30 2006 +0200
@@ -14,6 +14,7 @@
     import pickle
 
 from MoinMoin.util import lock
+from MoinMoin.packages import unpackLine
 
 
 class Tag(object):
@@ -33,6 +34,11 @@
     def __repr__(self):
         return u"<Tag remote_wiki=%r remote_rev=%r current_rev=%r>" % (self.remote_wiki, self.remote_rev, self.current_rev)
 
+    def __cmp__(self, other):
+        if not isinstance(other, Tag):
+            return NotImplemented
+        return cmp(self.current_rev, other.current_rev)
+
 
 class AbstractTagStore(object):
     """ This class is an abstract base class that shows how to implement classes
@@ -56,6 +62,10 @@
         """ Removes all tags. """
         return NotImplemented
 
+    def fetch(self, iwid_full=None, iw_name=None):
+        """ Fetches tags by a special IWID or interwiki name. """
+        return NotImplemented
+
 
 class PickleTagStore(AbstractTagStore):
     """ This class manages the storage of tags in pickle files. """
@@ -111,6 +121,17 @@
         self.tags = []
         self.commit()
 
+    def fetch(self, iwid_full=None, iw_name=None):
+        assert iwid_full ^ iw_name
+        if iwid_full:
+            iwid_full = unpackLine(iwid_full)
+            if len(iwid_full) == 1:
+                assert False, "This case is not supported yet" # XXX
+            iw_name = iwid_full[1]
+
+        return [t for t in self.tags if t.remote_wiki == iw_name]
+
+
 # currently we just have one implementation, so we do not need
 # a factory method
 TagStore = PickleTagStore
\ No newline at end of file
--- a/docs/CHANGES.aschremmer	Fri Aug 04 21:34:36 2006 +0200
+++ b/docs/CHANGES.aschremmer	Fri Aug 04 22:12:30 2006 +0200
@@ -8,11 +8,13 @@
 
   ToDo:
     * Implement actual syncronisation.
+      * Add correct IWID_full handling.
     * Implement a cross-site authentication system, i.e. mainly an
       identity storage.
     * Clean up trailing whitespace.
     * Add page locking, i.e. use the one in the new storage layer.
     * Check what needs to be documented on MoinMaster.
+    * Search for XXX
 
   New Features:
     * XMLRPC method to return the Moin version
@@ -83,6 +85,7 @@
          fixed option handling again, refined semantics of options, introduced
          direction option, replaced "localMatch"/"remoteMatch" by "pageMatch".
          Store mtime for InterWiki list updates and detect changes based on it.
+         Added support for localPrefix and remotePrefix.
 
 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