[Zope] ZSyncer.0.3.1 patch

Joseph Wayne Norton norton@arseed.co.jp
Tue, 19 Jun 2001 12:31:16 +0900


Andy -

I have made a patch to ZSyncer 0.3.1 that will constrain ZSyncer to
operate "relative to" and "only at and below" the level in which the
ZSyncer object has been installed. I also added https as a valid
prefix in the _check_http method.

This is useful to me because I can synchronize different staging areas
such as production, test, and development across different zope servers
and even within the same zope server.  The behavior of the current
version should be identical if the Zsyncer object is installed in the
root folder.

For example, I installed 2 ZSyncers at the following urls:

        http:/www.foo.com/vhosts/xyz.com/prd/zsyncer

        http:/www.foo.com/vhosts/xyz.com/tst/zsyncer

and specified the first url as the destination for the tst zsyncer.

Or similarly using different zope servers:

        http:/www.foo.com/vhosts/xyz.com/prd/zsyncer

        http:/tst.foo.com/vhosts/xyz.com/prd/zsyncer

Although I haven't investigated yet, the ZSyncer could simply use
"native" method calls instead of xmlrpc if the source and destination
ZSyncer object reside on the same zope server.

Please review and incorporate this patch if you feel that is is
applicable to you and others.

regards,

- joe n


diff -c --recursive ZSyncer/ZSyncer.py ZSyncer-new/ZSyncer.py
*** ZSyncer/ZSyncer.py  Sat Jun  2 19:24:39 2001
--- ZSyncer-new/ZSyncer.py      Tue Jun 19 11:15:14 2001
***************
*** 15,20 ****
--- 15,21 ----
  # needed for diff
  from OFS.History import html_diff, replace
  from string import join, split, atoi, strip
+ from re import sub
  from DocumentTemplate.DT_Util import html_quote
  from DocumentTemplate.DT_Var import url_quote_plus
  from types import StringType
***************
*** 154,160 ****
  
      def manage_srcXMLRPC(self, obj_path):
          """ Get a src from an object (if allowed) suitable for diffing """
!         try: obj = self.restrictedTraverse(obj_path)
          except KeyError: return 404
  
          c = getSecurityManager().checkPermission
--- 155,161 ----
  
      def manage_srcXMLRPC(self, obj_path):
          """ Get a src from an object (if allowed) suitable for diffing """
!         try: obj = self._restrictedTraverse(obj_path)
          except KeyError: return 404
  
          c = getSecurityManager().checkPermission
***************
*** 169,175 ****
          if type(obj_path) == type('string'): obj_path = string.split(obj_path, '/')
  
          # object lets try finding the parent
!         try: parent = self.restrictedTraverse(obj_path[:-1])
          except KeyError: return 404
  
          # lets check they are allowed to do this
--- 170,176 ----
          if type(obj_path) == type('string'): obj_path = string.split(obj_path, '/')
  
          # object lets try finding the parent
!         try: parent = self._restrictedTraverse(obj_path[:-1])
          except KeyError: return 404
  
          # lets check they are allowed to do this
***************
*** 208,219 ****
          ''' Gets a list of the objects '''
          obs = {}
          # go find the folder, then iterate through the subject
!         for ob in self.restrictedTraverse(string.split(folders, '/')).objectValues():
              # we dont to sync ZSyncers, that way leads much confusion
              if ob.meta_type != 'ZSyncer': 
                  o = {}
                  o['id'] = ob.getId()
!                 o['path'] = ob.getPhysicalPath()
                  o['title'] = ob.title_or_id()
                  o['meta_type'] = ob.meta_type
                  o['icon'] = ob.icon
--- 209,220 ----
          ''' Gets a list of the objects '''
          obs = {}
          # go find the folder, then iterate through the subject
!         for ob in self._restrictedTraverse(string.split(folders, '/')).objectValues():
              # we dont to sync ZSyncers, that way leads much confusion
              if ob.meta_type != 'ZSyncer': 
                  o = {}
                  o['id'] = ob.getId()
!                 o['path'] = self._getPhysicalPath(ob)
                  o['title'] = ob.title_or_id()
                  o['meta_type'] = ob.meta_type
                  o['icon'] = ob.icon
***************
*** 297,303 ****
  
      def _check_http(self, v):
          # so people can get away with leaving http:// off :)
!         if v[:7] != 'http://': v = 'http://%s' % v
          return v
  
      def _get_time(self):
--- 298,304 ----
  
      def _check_http(self, v):
          # so people can get away with leaving http:// off :)
!         if v[:7] != 'http://' and v[:8] != 'https://': v = 'http://%s' % v
          return v
  
      def _get_time(self):
***************
*** 336,349 ****
      def _exportXMLRPC(self, object=None, dest_url=None, add_in=1):
          """exports an object"""
          # go get the object
!         obj = self.restrictedTraverse(object)
          data = StringIO()
          obj._p_jar.exportFile(obj._p_oid, data)
  
          # do xml-rpc
          serverconn = self._serverConn(self._check_http(dest_url))
!         try: result = serverconn.manage_addXMLRPC(self._encode(data.getvalue()), obj.getPhysicalPath(), add_in)
          except: return 500
  
          # return result
          return result
--- 337,362 ----
      def _exportXMLRPC(self, object=None, dest_url=None, add_in=1):
          """exports an object"""
          # go get the object
!         obj = self._restrictedTraverse(object)
          data = StringIO()
          obj._p_jar.exportFile(obj._p_oid, data)
  
          # do xml-rpc
          serverconn = self._serverConn(self._check_http(dest_url))
!         try: result = serverconn.manage_addXMLRPC(self._encode(data.getvalue()), self._getPhysicalPath(obj), add_in)
          except: return 500
  
          # return result
          return result
+ 
+     def _restrictedTraverse(self, path):
+         base = join(self.getParentNode().getPhysicalPath(), '/')
+         if type(path) == type('string'):
+             base = base + path
+         elif path != ['']:
+             base = base + join(path, '/')
+         return self.restrictedTraverse(split(base, '/'))
+ 
+     def _getPhysicalPath(self, obj):
+         base = join(self.getParentNode().getPhysicalPath(), '/')
+         return split(sub('^' + base, '', join(obj.getPhysicalPath(), '/')), '/')