[Checkins] SVN: z3c.mountpoint/trunk/ - made it an egg
Michael Howitz
mh at gocept.com
Thu Jul 29 02:52:36 EDT 2010
Log message for revision 115190:
- made it an egg
- added a buildout
- fixed tests to run with current packages and without deprecation warnings
Changed:
A z3c.mountpoint/trunk/CHANGES.txt
D z3c.mountpoint/trunk/README.txt
D z3c.mountpoint/trunk/__init__.py
A z3c.mountpoint/trunk/bootstrap.py
D z3c.mountpoint/trunk/browser.py
D z3c.mountpoint/trunk/browser.zcml
A z3c.mountpoint/trunk/buildout.cfg
D z3c.mountpoint/trunk/configure.zcml
D z3c.mountpoint/trunk/connection.py
D z3c.mountpoint/trunk/interfaces.py
D z3c.mountpoint/trunk/mountpoint.py
D z3c.mountpoint/trunk/remoteproxy.py
A z3c.mountpoint/trunk/setup.py
A z3c.mountpoint/trunk/src/
A z3c.mountpoint/trunk/src/z3c/
A z3c.mountpoint/trunk/src/z3c/mountpoint/
A z3c.mountpoint/trunk/src/z3c/mountpoint/README.txt
A z3c.mountpoint/trunk/src/z3c/mountpoint/__init__.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/browser.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/browser.zcml
A z3c.mountpoint/trunk/src/z3c/mountpoint/configure.zcml
A z3c.mountpoint/trunk/src/z3c/mountpoint/connection.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/interfaces.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/mountpoint.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/remoteproxy.py
A z3c.mountpoint/trunk/src/z3c/mountpoint/tests.py
D z3c.mountpoint/trunk/tests.py
-=-
Added: z3c.mountpoint/trunk/CHANGES.txt
===================================================================
--- z3c.mountpoint/trunk/CHANGES.txt (rev 0)
+++ z3c.mountpoint/trunk/CHANGES.txt 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,10 @@
+============
+ Change log
+============
+
+0.1 (unreleased)
+================
+
+* Initial release.
+
+
Property changes on: z3c.mountpoint/trunk/CHANGES.txt
___________________________________________________________________
Added: svn:keywords
+ Id Rev Date
Added: svn:eol-style
+ native
Deleted: z3c.mountpoint/trunk/README.txt
===================================================================
--- z3c.mountpoint/trunk/README.txt 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/README.txt 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,122 +0,0 @@
-================
-ZODB Mount Point
-================
-
-This package provides a very simple implementation of a mount point for an
-object in another ZODB connection. If you have multiple connections defined in
-your ``zope.conf`` configuration file or multiple databases defined in your
-Python code, you can use this package to mount any object from any database at
-any location of another database.
-
-Let's start by creating two databases in the typical Zope 3 application layout:
-
- >>> from ZODB.tests.test_storage import MinimalMemoryStorage
- >>> from ZODB import DB
- >>> from zope.app.folder import rootFolder, Folder
- >>> import transaction
-
- >>> dbmap = {}
-
- >>> db1 = DB(MinimalMemoryStorage(), database_name='db1', databases=dbmap)
- >>> conn1 = db1.open()
- >>> conn1.root()['Application'] = rootFolder()
-
- >>> db2 = DB(MinimalMemoryStorage(), database_name='db2', databases=dbmap)
- >>> conn2 = db2.open()
- >>> conn2.root()['Application'] = rootFolder()
-
- >>> transaction.commit()
-
-Let's now add a sub-folder to the second database, which will serve as the
-object which we wish to mount:
-
- >>> conn2.root()['Application']['Folder2-1'] = Folder()
- >>> transaction.commit()
-
-We can now create a mount point:
-
- >>> from z3c.mountpoint import mountpoint
- >>> mountPoint = mountpoint.MountPoint(
- ... 'db2', objectPath=u'/Folder2-1', objectName=u'F2-1')
-
-The first argument to the constructor is the connection name of the database,
-the second argument is the path to the mounted object within the mounted DB
-and the object name is the name under which the object is mounted.
-
-Now we can add the mount point to the first database:
-
- >>> conn1.root()['Application']['mp'] = mountPoint
- >>> transaction.commit()
-
-We can now access the mounted object as follows:
-
- >>> conn1.root()['Application']['mp'].object
- <zope.app.folder.folder.Folder object at ...>
-
-Note that the object name is not yet used; it is for traversal only.
-
-
-Traversal
----------
-
-So let's have a look at the traversal next. Before being able to traverse, we
-need to register the special mount point traverser:
-
- >>> import zope.component
- >>> zope.component.provideAdapter(mountpoint.MountPointTraverser)
-
-We should now be able to traverse to the mounted object now:
-
- >>> from zope.publisher.browser import TestRequest
- >>> req = TestRequest()
-
- >>> from zope.app.publication.publicationtraverse import PublicationTraverser
- >>> traverser = PublicationTraverser()
- >>> traverser.traversePath(req, conn1.root()['Application'], 'mp/F2-1')
- <zope.app.folder.folder.Folder object at ...>
-
-When we add a new object remotely, it available via the mount point as well:
-
- >>> conn2.root()['Application']['Folder2-1']['Folder2-1.1'] = Folder()
- >>> transaction.commit()
-
- >>> tuple(traverser.traversePath(
- ... req, conn1.root()['Application'], 'mp/F2-1').keys())
- (u'Folder2-1.1',)
-
-Now, by default the objects refer to their original path:
-
- >>> f211 = traverser.traversePath(
- ... req, conn1.root()['Application'], 'mp/F2-1/Folder2-1.1')
-
- >>> from zope.traversing.browser import absoluteurl
- >>> absoluteurl.absoluteURL(f211, req)
- 'http://127.0.0.1/Folder2-1/Folder2-1.1'
-
-This package solves that problem by wrapping all object by a special remote
-location proxy and providing a special wrapping traverser for those proxies:
-
- >>> from z3c.mountpoint import remoteproxy
- >>> zope.component.provideAdapter(remoteproxy.RemoteLocationProxyTraverser)
-
- >>> f211 = traverser.traversePath(
- ... req, conn1.root()['Application'], 'mp/F2-1/Folder2-1.1')
- >>> absoluteurl.absoluteURL(f211, req)
- 'http://127.0.0.1/mp/F2-1/Folder2-1.1'
-
-
-Updating the Mount Point
-------------------------
-
-Whenever any attribute on the mount point is modified, the mount object is
-updated. For example, when the object path is changed, the object is adjusted
-as well. This is done with an event subscriber:
-
- >>> mountPoint.objectPath = u'/Folder2-1/Folder2-1.1'
-
- >>> modifiedEvent = object()
- >>> mountpoint.updateMountedObject(mountPoint, modifiedEvent)
-
- >>> f211 == mountPoint.object
- True
-
Deleted: z3c.mountpoint/trunk/__init__.py
===================================================================
--- z3c.mountpoint/trunk/__init__.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/__init__.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1 +0,0 @@
-# Make a package.
Copied: z3c.mountpoint/trunk/bootstrap.py (from rev 114727, zc.buildout/trunk/bootstrap/bootstrap.py)
===================================================================
--- z3c.mountpoint/trunk/bootstrap.py (rev 0)
+++ z3c.mountpoint/trunk/bootstrap.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,116 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+"""
+
+import os, shutil, sys, tempfile, urllib2
+from optparse import OptionParser
+
+tmpeggs = tempfile.mkdtemp()
+
+is_jython = sys.platform.startswith('java')
+
+# parsing arguments
+parser = OptionParser()
+parser.add_option("-v", "--version", dest="version",
+ help="use a specific zc.buildout version")
+parser.add_option("-d", "--distribute",
+ action="store_true", dest="distribute", default=False,
+ help="Use Disribute rather than Setuptools.")
+
+parser.add_option("-c", None, action="store", dest="config_file",
+ help=("Specify the path to the buildout configuration "
+ "file to be used."))
+
+options, args = parser.parse_args()
+
+# if -c was provided, we push it back into args for buildout' main function
+if options.config_file is not None:
+ args += ['-c', options.config_file]
+
+if options.version is not None:
+ VERSION = '==%s' % options.version
+else:
+ VERSION = ''
+
+USE_DISTRIBUTE = options.distribute
+args = args + ['bootstrap']
+
+try:
+ import pkg_resources
+ import setuptools
+ if not hasattr(pkg_resources, '_distribute'):
+ raise ImportError
+except ImportError:
+ ez = {}
+ if USE_DISTRIBUTE:
+ exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True)
+ else:
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ reload(sys.modules['pkg_resources'])
+ import pkg_resources
+
+if sys.platform == 'win32':
+ def quote(c):
+ if ' ' in c:
+ return '"%s"' % c # work around spawn lamosity on windows
+ else:
+ return c
+else:
+ def quote (c):
+ return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws = pkg_resources.working_set
+
+if USE_DISTRIBUTE:
+ requirement = 'distribute'
+else:
+ requirement = 'setuptools'
+
+if is_jython:
+ import subprocess
+
+ assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
+ quote(tmpeggs), 'zc.buildout' + VERSION],
+ env=dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse(requirement)).location
+ ),
+ ).wait() == 0
+
+else:
+ assert os.spawnle(
+ os.P_WAIT, sys.executable, quote (sys.executable),
+ '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse(requirement)).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout' + VERSION)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+shutil.rmtree(tmpeggs)
Deleted: z3c.mountpoint/trunk/browser.py
===================================================================
--- z3c.mountpoint/trunk/browser.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/browser.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,32 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Browser code
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-from zope.app.publisher.browser import menu, menumeta
-from zope.security.checker import CheckerPublic
-
-from z3c.mountpoint import interfaces
-
-def ObjectMenuItem(context, request):
- factory = menumeta.MenuItemFactory(
- menu.BrowserMenuItem,
- title=u'Object',
- action=context.objectName + '/@@SelectedManagementView.html',
- permission=CheckerPublic,
- order=2,
- _for=interfaces.IMountPoint)
- return factory(context, request)
Deleted: z3c.mountpoint/trunk/browser.zcml
===================================================================
--- z3c.mountpoint/trunk/browser.zcml 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/browser.zcml 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,40 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/browser"
- xmlns:zope="http://namespaces.zope.org/zope">
-
- <addform
- name="addMounPoint.html"
- schema=".interfaces.IMountPoint"
- label="Add a Mount Point"
- content_factory=".mountpoint.MountPoint"
- fields="connectionName objectPath objectName"
- set_before_add="connectionName objectPath objectName"
- permission="zope.ManageContent"
- />
-
- <addMenuItem
- class=".mountpoint.MountPoint"
- title="Mount Point"
- description="A Mount Point"
- permission="zope.ManageContent"
- view="addMounPoint.html"
- />
-
- <editform
- name="edit.html"
- schema=".interfaces.IMountPoint"
- label="Edit Mount Point"
- fields="connectionName objectPath objectName"
- permission="zope.ManageContent"
- menu="zmi_views" title="Edit"
- />
-
- <zope:adapter
- factory=".browser.ObjectMenuItem"
- for=".interfaces.IMountPoint
- zope.publisher.interfaces.browser.IDefaultBrowserLayer"
- provides="zope.app.menus.zmi_views"
- name="Object"
- />
-
-</configure>
Copied: z3c.mountpoint/trunk/buildout.cfg (from rev 100517, z3c.pagelet/trunk/buildout.cfg)
===================================================================
--- z3c.mountpoint/trunk/buildout.cfg (rev 0)
+++ z3c.mountpoint/trunk/buildout.cfg 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,7 @@
+[buildout]
+develop = .
+parts = test
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = z3c.mountpoint [test]
Deleted: z3c.mountpoint/trunk/configure.zcml
===================================================================
--- z3c.mountpoint/trunk/configure.zcml 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/configure.zcml 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,39 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- i18n_domain='zope'
- >
-
- <utility
- component=".connection.ZODBConnectionNamesVocabulary"
- provides="zope.schema.interfaces.IVocabularyFactory"
- name="ZODB Connection Names"
- />
-
- <class class=".mountpoint.MountPoint">
- <implements
- interface="zope.annotation.interfaces.IAttributeAnnotatable"
- />
- <require
- permission="zope.View"
- interface=".interfaces.IMountPoint"
- />
- <require
- permission="zope.ManageContent"
- set_schema=".interfaces.IMountPoint"
- />
- </class>
-
- <adapter
- factory=".mountpoint.MountPointTraverser"
- />
-
- <adapter
- factory=".remoteproxy.RemoteLocationProxyTraverser"
- />
-
- <subscriber handler=".mountpoint.updateMountedObject" />
-
- <include file="browser.zcml" />
-
-</configure>
Deleted: z3c.mountpoint/trunk/connection.py
===================================================================
--- z3c.mountpoint/trunk/connection.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/connection.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,25 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""A simple multi-database mount-point implementation
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-from zope.schema import vocabulary
-from zope.app.component import hooks
-
-def ZODBConnectionNamesVocabulary(context):
- return vocabulary.SimpleVocabulary(
- [vocabulary.SimpleTerm(name)
- for name in hooks.getSite()._p_jar.db().databases])
Deleted: z3c.mountpoint/trunk/interfaces.py
===================================================================
--- z3c.mountpoint/trunk/interfaces.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/interfaces.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,57 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""A simple multi-database mount-point implementation
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import zope.interface
-import zope.schema
-
-
-class IMountPoint(zope.interface.Interface):
- """A simple mount point."""
-
- connectionName = zope.schema.Choice(
- title=u'Conenction Name',
- vocabulary='ZODB Connection Names',
- required=True)
-
- objectPath = zope.schema.TextLine(
- title=u'Object Path',
- default=u'/',
- required=True)
-
- objectName = zope.schema.TextLine(
- title=u'Object Name',
- description=u'The name under which the object will be known '
- u'when traversing from the mount point.',
- default=u'object',
- required=True)
-
- object = zope.schema.Field(
- title=u'Foreign object')
-
- def update():
- """Update the mounted object."""
-
-
-class IRemoteLocationProxy(zope.interface.Interface):
- """Remote Location Proxy
-
- When an object from a different object database is used, the directly
- specified parent is not the correct one anymore. The parent should point
- to the local mount point and subsequent objects in the path to the
- location proxied parent.
- """
Deleted: z3c.mountpoint/trunk/mountpoint.py
===================================================================
--- z3c.mountpoint/trunk/mountpoint.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/mountpoint.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,82 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""A simple multi-database mount-point implementation
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import persistent
-import zope.component
-import zope.interface
-import zope.lifecycleevent
-import zope.location
-from zope.app.container import contained
-from zope.app.publication import traversers
-from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPublisher
-from zope.security.proxy import removeSecurityProxy
-from zope.traversing import api
-
-from z3c.mountpoint import interfaces, remoteproxy
-
-class MountPoint(persistent.Persistent, contained.Contained):
- """A simple mount point."""
- zope.interface.implements(interfaces.IMountPoint)
-
- def __init__(self, connectionName=None, objectPath=u'/', objectName=u'object'):
- self.connectionName = connectionName
- self.objectPath = objectPath
- self.objectName = objectName
- self.object = None
-
- def update(self):
- parent = self.__parent__
- if parent is not None:
- # Get the connection by name
- conn = parent._p_jar.get_connection(self.connectionName)
- obj = conn.root()['Application']
- obj = api.traverse(obj, self.objectPath)
- self.object = obj
- else:
- self.object = None
-
- @apply
- def __parent__():
- def get(self):
- return self and self.__dict__.get('__parent__', None)
- def set(self, parent):
- self.__dict__['__parent__'] = parent
- self.update()
- return property(get, set)
-
-
-class MountPointTraverser(traversers.SimpleComponentTraverser):
-
- zope.component.adapts(interfaces.IMountPoint, IBrowserRequest)
- zope.interface.implementsOnly(IBrowserPublisher)
-
- def publishTraverse(self, request, name):
- if name == self.context.objectName:
- # Remove the security proxy, because we need a bare object to wrap
- # the location proxy around.
- context = removeSecurityProxy(self.context)
- return remoteproxy.RemoteLocationProxy(
- context.object, context, self.context.objectName)
- return super(MountPointTraverser, self).publishTraverse(
- request, name)
-
-
- at zope.component.adapter(
- interfaces.IMountPoint, zope.lifecycleevent.IObjectModifiedEvent)
-def updateMountedObject(mountPoint, event):
- mountPoint.update()
Deleted: z3c.mountpoint/trunk/remoteproxy.py
===================================================================
--- z3c.mountpoint/trunk/remoteproxy.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/remoteproxy.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Remote object traverser.
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import zope.interface
-from zope.interface import declarations
-from zope.proxy import getProxiedObject, removeAllProxies
-from zope.proxy.decorator import DecoratorSpecificationDescriptor
-from zope.publisher.interfaces.browser import IBrowserPublisher, IBrowserRequest
-
-from z3c.mountpoint import interfaces
-
-class RemoteLocationProxyDecoratorSpecificationDescriptor(
- DecoratorSpecificationDescriptor):
-
- def __get__(self, inst, cls=None):
- if inst is None:
- return declarations.getObjectSpecification(cls)
- else:
- provided = zope.interface.providedBy(getProxiedObject(inst))
-
- # Use type rather than __class__ because inst is a proxy and
- # will return the proxied object's class.
- cls = type(inst)
- # Create a special version of Provides, which forces the remote
- # location proxy to the front, so that a special traverser can be
- # enforced.
- return declarations.Provides(
- cls, interfaces.IRemoteLocationProxy, provided)
-
-
-class RemoteLocationProxy(zope.location.LocationProxy):
- """A location proxy for remote objects."""
- __providedBy__ = RemoteLocationProxyDecoratorSpecificationDescriptor()
-
-
-class RemoteLocationProxyTraverser(object):
- zope.component.adapts(interfaces.IRemoteLocationProxy, IBrowserRequest)
- zope.interface.implements(IBrowserPublisher)
-
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
- def browserDefault(self, request):
- ob = self.context
- view_name = zapi.getDefaultViewName(ob, request)
- return ob, (view_name,)
-
- def publishTraverse(self, request, name):
- pureContext = removeAllProxies(self.context)
- traverser = zope.component.getMultiAdapter(
- (pureContext, self.request), IBrowserPublisher)
- result = traverser.publishTraverse(request, name)
- # Only remove the security proxy from the context.
- return RemoteLocationProxy(result, getProxiedObject(self.context), name)
Copied: z3c.mountpoint/trunk/setup.py (from rev 100519, z3c.pagelet/trunk/setup.py)
===================================================================
--- z3c.mountpoint/trunk/setup.py (rev 0)
+++ z3c.mountpoint/trunk/setup.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,85 @@
+##############################################################################
+#
+# Copyright (c) 2007-2009 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Setup
+
+$Id$
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+ return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+version = '0.1dev'
+
+setup(
+ name='z3c.mountpoint',
+ version=version,
+ author = "Stephan Richter and the Zope Community",
+ author_email = "zope-dev at zope.org",
+ description = (
+ "Very simple implementation of a mount point for an object in "
+ "another ZODB connection."),
+ long_description=(
+ read('src', 'z3c', 'mountpoint', 'README.txt')
+ + '\n\n' +
+ read('CHANGES.txt')
+ ),
+ license = "ZPL 2.1",
+ keywords = "zope3 zodb mount mountpoint",
+ classifiers = [
+ 'Development Status :: 3 - Alpha',
+ 'Environment :: Web Environment',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Zope Public License',
+ 'Programming Language :: Python',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Framework :: Zope3'],
+ url = 'http://pypi.python.org/pypi/z3c.mountpoint',
+ packages = find_packages('src'),
+ package_dir = {'':'src'},
+ namespace_packages = ['z3c'],
+ extras_require = dict(
+ test = [
+ 'zope.app.testing',
+ 'zope.app.publication',
+ # 'zope.testing',
+ # 'zope.traversing',
+ # 'lxml>=2.1.1',
+ # 'z3c.pt>=1.0b4',
+ # 'z3c.ptcompat',
+ # 'zope.app.security',
+ # 'zope.formlib',
+ ],
+ ),
+ install_requires = [
+ 'setuptools',
+ # 'z3c.template>=1.2.0',
+ # 'z3c.ptcompat',
+ # # TODO: this is only needed for ZCML directives, so can copy
+ # 'zope.app.publisher', # things we use from there and get rid of the dependencies.
+ 'zope.component',
+ 'zope.app.container',
+ # 'zope.configuration',
+ # 'zope.contentprovider',
+ # 'zope.interface',
+ # 'zope.publisher',
+ # 'zope.schema',
+ # 'zope.security',
+ ],
+ include_package_data = True,
+ zip_safe = False,
+ )
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/README.txt (from rev 115115, z3c.mountpoint/trunk/README.txt)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/README.txt (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/README.txt 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,122 @@
+================
+ZODB Mount Point
+================
+
+This package provides a very simple implementation of a mount point for an
+object in another ZODB connection. If you have multiple connections defined in
+your ``zope.conf`` configuration file or multiple databases defined in your
+Python code, you can use this package to mount any object from any database at
+any location of another database.
+
+Let's start by creating two databases in the typical Zope 3 application layout:
+
+ >>> from ZODB.tests.test_storage import MinimalMemoryStorage
+ >>> from ZODB import DB
+ >>> from zope.site.folder import rootFolder, Folder
+ >>> import transaction
+
+ >>> dbmap = {}
+
+ >>> db1 = DB(MinimalMemoryStorage(), database_name='db1', databases=dbmap)
+ >>> conn1 = db1.open()
+ >>> conn1.root()['Application'] = rootFolder()
+
+ >>> db2 = DB(MinimalMemoryStorage(), database_name='db2', databases=dbmap)
+ >>> conn2 = db2.open()
+ >>> conn2.root()['Application'] = rootFolder()
+
+ >>> transaction.commit()
+
+Let's now add a sub-folder to the second database, which will serve as the
+object which we wish to mount:
+
+ >>> conn2.root()['Application']['Folder2-1'] = Folder()
+ >>> transaction.commit()
+
+We can now create a mount point:
+
+ >>> from z3c.mountpoint import mountpoint
+ >>> mountPoint = mountpoint.MountPoint(
+ ... 'db2', objectPath=u'/Folder2-1', objectName=u'F2-1')
+
+The first argument to the constructor is the connection name of the database,
+the second argument is the path to the mounted object within the mounted DB
+and the object name is the name under which the object is mounted.
+
+Now we can add the mount point to the first database:
+
+ >>> conn1.root()['Application']['mp'] = mountPoint
+ >>> transaction.commit()
+
+We can now access the mounted object as follows:
+
+ >>> conn1.root()['Application']['mp'].object
+ <zope.site.folder.Folder object at ...>
+
+Note that the object name is not yet used; it is for traversal only.
+
+
+Traversal
+---------
+
+So let's have a look at the traversal next. Before being able to traverse, we
+need to register the special mount point traverser:
+
+ >>> import zope.component
+ >>> zope.component.provideAdapter(mountpoint.MountPointTraverser)
+
+We should now be able to traverse to the mounted object now:
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> req = TestRequest()
+
+ >>> from zope.traversing.publicationtraverse import PublicationTraverser
+ >>> traverser = PublicationTraverser()
+ >>> traverser.traversePath(req, conn1.root()['Application'], 'mp/F2-1')
+ <zope.site.folder.Folder object at ...>
+
+When we add a new object remotely, it available via the mount point as well:
+
+ >>> conn2.root()['Application']['Folder2-1']['Folder2-1.1'] = Folder()
+ >>> transaction.commit()
+
+ >>> tuple(traverser.traversePath(
+ ... req, conn1.root()['Application'], 'mp/F2-1').keys())
+ (u'Folder2-1.1',)
+
+Now, by default the objects refer to their original path:
+
+ >>> f211 = traverser.traversePath(
+ ... req, conn1.root()['Application'], 'mp/F2-1/Folder2-1.1')
+
+ >>> from zope.traversing.browser import absoluteurl
+ >>> absoluteurl.absoluteURL(f211, req)
+ 'http://127.0.0.1/Folder2-1/Folder2-1.1'
+
+This package solves that problem by wrapping all object by a special remote
+location proxy and providing a special wrapping traverser for those proxies:
+
+ >>> from z3c.mountpoint import remoteproxy
+ >>> zope.component.provideAdapter(remoteproxy.RemoteLocationProxyTraverser)
+
+ >>> f211 = traverser.traversePath(
+ ... req, conn1.root()['Application'], 'mp/F2-1/Folder2-1.1')
+ >>> absoluteurl.absoluteURL(f211, req)
+ 'http://127.0.0.1/mp/F2-1/Folder2-1.1'
+
+
+Updating the Mount Point
+------------------------
+
+Whenever any attribute on the mount point is modified, the mount object is
+updated. For example, when the object path is changed, the object is adjusted
+as well. This is done with an event subscriber:
+
+ >>> mountPoint.objectPath = u'/Folder2-1/Folder2-1.1'
+
+ >>> modifiedEvent = object()
+ >>> mountpoint.updateMountedObject(mountPoint, modifiedEvent)
+
+ >>> f211 == mountPoint.object
+ True
+
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/__init__.py (from rev 115115, z3c.mountpoint/trunk/__init__.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/__init__.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/__init__.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1 @@
+# Make a package.
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/browser.py (from rev 115115, z3c.mountpoint/trunk/browser.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/browser.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/browser.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,32 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser code
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.app.publisher.browser import menu, menumeta
+from zope.security.checker import CheckerPublic
+
+from z3c.mountpoint import interfaces
+
+def ObjectMenuItem(context, request):
+ factory = menumeta.MenuItemFactory(
+ menu.BrowserMenuItem,
+ title=u'Object',
+ action=context.objectName + '/@@SelectedManagementView.html',
+ permission=CheckerPublic,
+ order=2,
+ _for=interfaces.IMountPoint)
+ return factory(context, request)
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/browser.zcml (from rev 115115, z3c.mountpoint/trunk/browser.zcml)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/browser.zcml (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/browser.zcml 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,40 @@
+<configure
+ xmlns="http://namespaces.zope.org/browser"
+ xmlns:zope="http://namespaces.zope.org/zope">
+
+ <addform
+ name="addMounPoint.html"
+ schema=".interfaces.IMountPoint"
+ label="Add a Mount Point"
+ content_factory=".mountpoint.MountPoint"
+ fields="connectionName objectPath objectName"
+ set_before_add="connectionName objectPath objectName"
+ permission="zope.ManageContent"
+ />
+
+ <addMenuItem
+ class=".mountpoint.MountPoint"
+ title="Mount Point"
+ description="A Mount Point"
+ permission="zope.ManageContent"
+ view="addMounPoint.html"
+ />
+
+ <editform
+ name="edit.html"
+ schema=".interfaces.IMountPoint"
+ label="Edit Mount Point"
+ fields="connectionName objectPath objectName"
+ permission="zope.ManageContent"
+ menu="zmi_views" title="Edit"
+ />
+
+ <zope:adapter
+ factory=".browser.ObjectMenuItem"
+ for=".interfaces.IMountPoint
+ zope.publisher.interfaces.browser.IDefaultBrowserLayer"
+ provides="zope.app.menus.zmi_views"
+ name="Object"
+ />
+
+</configure>
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/configure.zcml (from rev 115115, z3c.mountpoint/trunk/configure.zcml)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/configure.zcml (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/configure.zcml 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,39 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain='zope'
+ >
+
+ <utility
+ component=".connection.ZODBConnectionNamesVocabulary"
+ provides="zope.schema.interfaces.IVocabularyFactory"
+ name="ZODB Connection Names"
+ />
+
+ <class class=".mountpoint.MountPoint">
+ <implements
+ interface="zope.annotation.interfaces.IAttributeAnnotatable"
+ />
+ <require
+ permission="zope.View"
+ interface=".interfaces.IMountPoint"
+ />
+ <require
+ permission="zope.ManageContent"
+ set_schema=".interfaces.IMountPoint"
+ />
+ </class>
+
+ <adapter
+ factory=".mountpoint.MountPointTraverser"
+ />
+
+ <adapter
+ factory=".remoteproxy.RemoteLocationProxyTraverser"
+ />
+
+ <subscriber handler=".mountpoint.updateMountedObject" />
+
+ <include file="browser.zcml" />
+
+</configure>
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/connection.py (from rev 115115, z3c.mountpoint/trunk/connection.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/connection.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/connection.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,25 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""A simple multi-database mount-point implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.schema import vocabulary
+from zope.app.component import hooks
+
+def ZODBConnectionNamesVocabulary(context):
+ return vocabulary.SimpleVocabulary(
+ [vocabulary.SimpleTerm(name)
+ for name in hooks.getSite()._p_jar.db().databases])
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/interfaces.py (from rev 115115, z3c.mountpoint/trunk/interfaces.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/interfaces.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/interfaces.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""A simple multi-database mount-point implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+import zope.schema
+
+
+class IMountPoint(zope.interface.Interface):
+ """A simple mount point."""
+
+ connectionName = zope.schema.Choice(
+ title=u'Conenction Name',
+ vocabulary='ZODB Connection Names',
+ required=True)
+
+ objectPath = zope.schema.TextLine(
+ title=u'Object Path',
+ default=u'/',
+ required=True)
+
+ objectName = zope.schema.TextLine(
+ title=u'Object Name',
+ description=u'The name under which the object will be known '
+ u'when traversing from the mount point.',
+ default=u'object',
+ required=True)
+
+ object = zope.schema.Field(
+ title=u'Foreign object')
+
+ def update():
+ """Update the mounted object."""
+
+
+class IRemoteLocationProxy(zope.interface.Interface):
+ """Remote Location Proxy
+
+ When an object from a different object database is used, the directly
+ specified parent is not the correct one anymore. The parent should point
+ to the local mount point and subsequent objects in the path to the
+ location proxied parent.
+ """
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/mountpoint.py (from rev 115115, z3c.mountpoint/trunk/mountpoint.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/mountpoint.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/mountpoint.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""A simple multi-database mount-point implementation
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import persistent
+import zope.component
+import zope.interface
+import zope.lifecycleevent
+import zope.location
+from zope.app.container import contained
+from zope.app.publication import traversers
+from zope.publisher.interfaces.browser import IBrowserRequest, IBrowserPublisher
+from zope.security.proxy import removeSecurityProxy
+from zope.traversing import api
+
+from z3c.mountpoint import interfaces, remoteproxy
+
+class MountPoint(persistent.Persistent, contained.Contained):
+ """A simple mount point."""
+ zope.interface.implements(interfaces.IMountPoint)
+
+ def __init__(self, connectionName=None, objectPath=u'/', objectName=u'object'):
+ self.connectionName = connectionName
+ self.objectPath = objectPath
+ self.objectName = objectName
+ self.object = None
+
+ def update(self):
+ parent = self.__parent__
+ if parent is not None:
+ # Get the connection by name
+ conn = parent._p_jar.get_connection(self.connectionName)
+ obj = conn.root()['Application']
+ obj = api.traverse(obj, self.objectPath)
+ self.object = obj
+ else:
+ self.object = None
+
+ @apply
+ def __parent__():
+ def get(self):
+ return self and self.__dict__.get('__parent__', None)
+ def set(self, parent):
+ self.__dict__['__parent__'] = parent
+ self.update()
+ return property(get, set)
+
+
+class MountPointTraverser(traversers.SimpleComponentTraverser):
+
+ zope.component.adapts(interfaces.IMountPoint, IBrowserRequest)
+ zope.interface.implementsOnly(IBrowserPublisher)
+
+ def publishTraverse(self, request, name):
+ if name == self.context.objectName:
+ # Remove the security proxy, because we need a bare object to wrap
+ # the location proxy around.
+ context = removeSecurityProxy(self.context)
+ return remoteproxy.RemoteLocationProxy(
+ context.object, context, self.context.objectName)
+ return super(MountPointTraverser, self).publishTraverse(
+ request, name)
+
+
+ at zope.component.adapter(
+ interfaces.IMountPoint, zope.lifecycleevent.IObjectModifiedEvent)
+def updateMountedObject(mountPoint, event):
+ mountPoint.update()
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/remoteproxy.py (from rev 115115, z3c.mountpoint/trunk/remoteproxy.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/remoteproxy.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/remoteproxy.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Remote object traverser.
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.interface
+from zope.interface import declarations
+from zope.proxy import getProxiedObject, removeAllProxies
+from zope.proxy.decorator import DecoratorSpecificationDescriptor
+from zope.publisher.interfaces.browser import IBrowserPublisher, IBrowserRequest
+
+from z3c.mountpoint import interfaces
+
+class RemoteLocationProxyDecoratorSpecificationDescriptor(
+ DecoratorSpecificationDescriptor):
+
+ def __get__(self, inst, cls=None):
+ if inst is None:
+ return declarations.getObjectSpecification(cls)
+ else:
+ provided = zope.interface.providedBy(getProxiedObject(inst))
+
+ # Use type rather than __class__ because inst is a proxy and
+ # will return the proxied object's class.
+ cls = type(inst)
+ # Create a special version of Provides, which forces the remote
+ # location proxy to the front, so that a special traverser can be
+ # enforced.
+ return declarations.Provides(
+ cls, interfaces.IRemoteLocationProxy, provided)
+
+
+class RemoteLocationProxy(zope.location.LocationProxy):
+ """A location proxy for remote objects."""
+ __providedBy__ = RemoteLocationProxyDecoratorSpecificationDescriptor()
+
+
+class RemoteLocationProxyTraverser(object):
+ zope.component.adapts(interfaces.IRemoteLocationProxy, IBrowserRequest)
+ zope.interface.implements(IBrowserPublisher)
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def browserDefault(self, request):
+ ob = self.context
+ view_name = zapi.getDefaultViewName(ob, request)
+ return ob, (view_name,)
+
+ def publishTraverse(self, request, name):
+ pureContext = removeAllProxies(self.context)
+ traverser = zope.component.getMultiAdapter(
+ (pureContext, self.request), IBrowserPublisher)
+ result = traverser.publishTraverse(request, name)
+ # Only remove the security proxy from the context.
+ return RemoteLocationProxy(result, getProxiedObject(self.context), name)
Copied: z3c.mountpoint/trunk/src/z3c/mountpoint/tests.py (from rev 115115, z3c.mountpoint/trunk/tests.py)
===================================================================
--- z3c.mountpoint/trunk/src/z3c/mountpoint/tests.py (rev 0)
+++ z3c.mountpoint/trunk/src/z3c/mountpoint/tests.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -0,0 +1,53 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Browser code
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from zope.app.publication import traversers
+from zope.app.testing import placelesssetup, setup
+from zope.publisher.interfaces.browser import IBrowserPublisher, IBrowserRequest
+from zope.security import checker
+from zope.site import folder
+from zope.site.interfaces import IFolder
+from zope.traversing.testing import setUp as traversalSetUp
+import doctest
+import unittest
+import zope.component
+import zope.interface
+
+from z3c.mountpoint import interfaces, mountpoint
+
+def setUp(test):
+ placelesssetup.setUp(test)
+ traversalSetUp()
+ # The test traverser is all we need.
+ zope.component.provideAdapter(
+ traversers.TestTraverser,
+ (zope.interface.Interface, IBrowserRequest), IBrowserPublisher)
+ # A simple interface checker for: MountPoint
+ checker.defineChecker(
+ mountpoint.MountPoint, checker.InterfaceChecker(interfaces.IMountPoint))
+ # A simple interface checker for: Folder
+ checker.defineChecker(
+ folder.Folder, checker.InterfaceChecker(IFolder))
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('README.txt',
+ setUp=setUp, tearDown=placelesssetup.tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
Deleted: z3c.mountpoint/trunk/tests.py
===================================================================
--- z3c.mountpoint/trunk/tests.py 2010-07-29 06:50:08 UTC (rev 115189)
+++ z3c.mountpoint/trunk/tests.py 2010-07-29 06:52:35 UTC (rev 115190)
@@ -1,53 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Browser code
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import unittest
-import zope.component
-import zope.interface
-from zope.app.folder import folder
-from zope.app.folder.interfaces import IFolder
-from zope.app.publication import traversers
-from zope.app.testing import placelesssetup, setup
-from zope.publisher.interfaces.browser import IBrowserPublisher, IBrowserRequest
-from zope.security import checker
-from zope.testing import doctest
-from zope.traversing.testing import setUp as traversalSetUp
-
-from z3c.mountpoint import interfaces, mountpoint
-
-def setUp(test):
- placelesssetup.setUp(test)
- traversalSetUp()
- # The test traverser is all we need.
- zope.component.provideAdapter(
- traversers.TestTraverser,
- (zope.interface.Interface, IBrowserRequest), IBrowserPublisher)
- # A simple interface checker for: MountPoint
- checker.defineChecker(
- mountpoint.MountPoint, checker.InterfaceChecker(interfaces.IMountPoint))
- # A simple interface checker for: Folder
- checker.defineChecker(
- folder.Folder, checker.InterfaceChecker(IFolder))
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocFileSuite('README.txt',
- setUp=setUp, tearDown=placelesssetup.tearDown,
- optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
- ),
- ))
More information about the checkins
mailing list