[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