[Zope3-checkins]
SVN: Zope3/trunk/src/zope/app/apidoc/utilitymodule/
Fixed utility module to work well with any type of utility name.
Stephan Richter
srichter at cosmos.phy.tufts.edu
Fri Oct 28 14:33:13 EDT 2005
Log message for revision 39694:
Fixed utility module to work well with any type of utility name.
Changed:
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/README.txt
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.py
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.txt
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/configure.zcml
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/index.pt
U Zope3/trunk/src/zope/app/apidoc/utilitymodule/utilitymodule.py
-=-
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/README.txt 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/README.txt 2005-10-28 18:33:12 UTC (rev 39694)
@@ -23,7 +23,7 @@
>>> from zope.app.testing import ztapi
>>> ztapi.provideUtility(IDocumentationModule, module, 'Utility')
-Now we can get a single utility interface by path:
+Now we can get a single utility interface by path:
>>> module.get('zope.app.apidoc.interfaces.IDocumentationModule')
<zope.app.apidoc.utilitymodule.utilitymodule.UtilityInterface ...>
@@ -31,9 +31,9 @@
and list all available interfaces:
>>> module.items()
- [('zope.app.apidoc.interfaces.IDocumentationModule',
- <zope.app.apidoc.utilitymodule.utilitymodule.UtilityInterface ...>),
- ('zope.security.interfaces.IPermission',
+ [('zope.app.apidoc.interfaces.IDocumentationModule',
+ <zope.app.apidoc.utilitymodule.utilitymodule.UtilityInterface ...>),
+ ('zope.security.interfaces.IPermission',
<zope.app.apidoc.utilitymodule.utilitymodule.UtilityInterface ...>)]
@@ -48,7 +48,7 @@
>>> ut_iface = UtilityInterface(
... module,
... 'zope.app.apidoc.interfaces.IDocumentationModule',
- ... IDocumentationModule)
+ ... IDocumentationModule)
Now we can get the utility:
@@ -64,7 +64,7 @@
>>> from zope.app.apidoc.utilitymodule.utilitymodule import NONAME
>>> ut_iface.get(NONAME).component
- <zope.app.apidoc.utilitymodule.utilitymodule.UtilityModule object at ...>
+ <zope.app.apidoc.utilitymodule.utilitymodule.UtilityModule object at ...>
If you try to get a non-existent utility, `None` is returned:
@@ -74,5 +74,35 @@
You can get a list of available utilities as well, of course:
>>> ut_iface.items()
- [('Utility', <zope.app.apidoc.utilitymodule.utilitymodule.Utility ...>),
- ('__noname__', <zope.app.apidoc.utilitymodule.utilitymodule.Utility ...>)]
+ [('VXRpbGl0eQ==', <...apidoc.utilitymodule.utilitymodule.Utility ...>),
+ ('X19ub25hbWVfXw==', <...apidoc.utilitymodule.utilitymodule.Utility ...>)]
+
+Bu what are those strange names? Since utility names can be any string, it is
+hard to deal with them in a URL. Thus the system will advertise and use the
+names in their `BASE64` encoded form. However, because it is easier in the
+Python API to use the real utility names, utilities can be looked up in their
+original form as well.
+
+
+Encoding and Decoding Names
+---------------------------
+
+The utility names are en- and decoded using two helper methods:
+
+ >>> from zope.app.apidoc.utilitymodule.utilitymodule import encodeName
+ >>> from zope.app.apidoc.utilitymodule.utilitymodule import decodeName
+
+Round trips of encoding and decoding should be possible:
+
+ >>> encoded = encodeName(u'Some Utility')
+ >>> encoded
+ 'U29tZSBVdGlsaXR5'
+
+ >>> decodeName(encoded)
+ u'Some Utility'
+
+If a string is not encoded, the decoding process will simply return the
+original string:
+
+ >>> decodeName(u'Some Utility')
+ u'Some Utility'
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.py 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.py 2005-10-28 18:33:12 UTC (rev 39694)
@@ -29,13 +29,13 @@
def getName(self):
"""Get the name of the utility."""
- name = zapi.name(self.context)
+ name = self.context.name
if name == NONAME:
return 'no name'
return name
def getInterface(self):
- """Return the interface the utility provides."""
+ """Return the interface the utility provides."""
schema = LocationProxy(self.context.interface,
self.context,
getPythonPath(self.context.interface))
@@ -46,7 +46,7 @@
"""Return the python path of the implementation class."""
# We could use `type()` here, but then we would need to remove the
# security proxy from the component. This is easier and also supports
- # old-style classes
+ # old-style classes
klass = self.context.component.__class__
return {'path': getPythonPath(klass),
@@ -59,11 +59,11 @@
def getMenuTitle(self, node):
"""Return the title of the node that is displayed in the menu."""
obj = node.context
- if zapi.name(obj) == NONAME:
- return 'no name'
if zapi.isinstance(obj, UtilityInterface):
return zapi.name(obj).split('.')[-1]
- return zapi.name(obj)
+ if obj.name == NONAME:
+ return 'no name'
+ return obj.name
def getMenuLink(self, node):
"""Return the HTML link of the node that is displayed in the menu."""
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.txt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.txt 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/browser.txt 2005-10-28 18:33:12 UTC (rev 39694)
@@ -8,7 +8,7 @@
This is a class that helps building the menu. The `menu_macros` expect the menu
view class to have the `getMenuTitle(node)` and `getMenuLink(node)` methods
-implemented. `node` is a `zope.app.tree.node.Node` instance.
+implemented. `node` is a `zope.app.tree.node.Node` instance.
Let's start by creating the menu:
@@ -24,7 +24,7 @@
and then wrap it in a node:
- >>> from zope.app.tree.node import Node
+ >>> from zope.app.tree.node import Node
>>> node = Node(uiface)
You can now get the title and link from the menu:
@@ -39,7 +39,7 @@
>>> foobar_reg = type(
... 'RegistrationStub', (),
- ... {'name': 'FooBar', 'provided': None,
+ ... {'name': 'FooBar', 'provided': None,
... 'component': None, 'doc': ''})()
which is then wrapped in a `Utility` documentation class and then in a node:
@@ -53,14 +53,14 @@
>>> menu.getMenuTitle(node)
'FooBar'
>>> menu.getMenuLink(node)
- './foo.bar.iface/FooBar/index.html'
+ './foo.bar.iface/Rm9vQmFy/index.html'
Finally, we get menu title and link for a utility without a name:
>>> from zope.app.apidoc.utilitymodule.utilitymodule import NONAME
>>> noname_reg = type(
... 'RegistrationStub', (),
- ... {'name': NONAME, 'provided': None,
+ ... {'name': NONAME, 'provided': None,
... 'component': None, 'doc': ''})()
>>> util = Utility(uiface, noname_reg)
@@ -68,7 +68,7 @@
>>> menu.getMenuTitle(node)
'no name'
>>> menu.getMenuLink(node)
- './foo.bar.iface/__noname__/index.html'
+ './foo.bar.iface/X19ub25hbWVfXw==/index.html'
`UtilityDetails` class
@@ -78,7 +78,7 @@
`getName()`
-----------
-
+
Get the name of the utility.
>>> from zope.app.apidoc.utilitymodule.browser import UtilityDetails
@@ -108,7 +108,7 @@
>>> blah_reg = type(
... 'RegistrationStub', (),
- ... {'name': 'Blah', 'provided': IBlah,
+ ... {'name': 'Blah', 'provided': IBlah,
... 'component': None, 'doc': ''})()
Then we wrap the registration in the utility documentation class and create
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/configure.zcml 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/configure.zcml 2005-10-28 18:33:12 UTC (rev 39694)
@@ -8,7 +8,7 @@
</class>
<class class=".utilitymodule.Utility">
- <allow attributes="registration interface component doc" />
+ <allow attributes="name registration interface component doc" />
</class>
<class class=".utilitymodule.UtilityInterface">
@@ -27,13 +27,13 @@
class=".browser.Menu"
name="menu.html"
template="menu.pt" />
-
+
<browser:page
for=".utilitymodule.UtilityModule"
permission="zope.app.apidoc.UseAPIDoc"
class=".browser.Menu"
name="staticmenu.html"
- template="static_menu.pt" />
+ template="static_menu.pt" />
<browser:page
for=".utilitymodule.Utility"
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/index.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/index.pt 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/index.pt 2005-10-28 18:33:12 UTC (rev 39694)
@@ -13,13 +13,13 @@
tal:replace="view/getName" i18n:name="name" />")</tal:block>
</h1>
- <div class="indent"
+ <div class="indent"
tal:define="component view/getComponent"
tal:condition="component">
<h3>
<span i18n:translate="">Component:</span>
<a href=""
- tal:attributes="href
+ tal:attributes="href
string:../../../Code/${component/url}/index.html"
tal:content="component/path" /></h3>
</div>
Modified: Zope3/trunk/src/zope/app/apidoc/utilitymodule/utilitymodule.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/utilitymodule/utilitymodule.py 2005-10-28 18:29:50 UTC (rev 39693)
+++ Zope3/trunk/src/zope/app/apidoc/utilitymodule/utilitymodule.py 2005-10-28 18:33:12 UTC (rev 39694)
@@ -17,6 +17,8 @@
"""
__docformat__ = 'restructuredtext'
+import base64, binascii
+
from zope.component.site import UtilityRegistration
from zope.interface import implements
@@ -30,14 +32,24 @@
# Constant used when the utility has no name
NONAME = '__noname__'
+def encodeName(name):
+ return base64.encodestring(name.encode('utf-8')).strip()
+
+def decodeName(name):
+ try:
+ return base64.decodestring(name).decode('utf-8')
+ except binascii.Error:
+ return name
+
class Utility(object):
"""Representation of a utility for the API Documentation"""
implements(ILocation)
-
+
def __init__(self, parent, reg):
"""Initialize Utility object."""
self.__parent__ = parent
- self.__name__ = reg.name or NONAME
+ self.__name__ = encodeName(reg.name or NONAME)
+ self.name = reg.name or NONAME
self.registration = reg
self.interface = reg.provided
self.component = reg.component
@@ -56,6 +68,7 @@
def get(self, key, default=None):
"""See zope.app.container.interfaces.IReadContainer"""
sm = zapi.getGlobalSiteManager()
+ key = decodeName(key)
if key == NONAME:
key = ''
utils = [Utility(self, reg)
@@ -67,7 +80,7 @@
def items(self):
"""See zope.app.container.interfaces.IReadContainer"""
sm = zapi.getGlobalSiteManager()
- items = [(reg.name or NONAME, Utility(self, reg))
+ items = [(encodeName(reg.name or NONAME), Utility(self, reg))
for reg in sm.registrations()
if zapi.isinstance(reg, UtilityRegistration) and \
self.interface == reg.provided]
More information about the Zope3-Checkins
mailing list