def getViewFactoryData(factory):
    """Squeeze some useful information out of the view factory"""
    info = {'path': None, 'url': None, 'template': None, 'resource': None,
            'referencable': True}

    # Always determine the most basic factory
    # Commonly, factories are wrapped to provide security or location, for
    # example. If those wrappers play nice, then they provide a `factory`
    # attribute, that points to the original factory.
    while hasattr(factory, 'factory'):
        factory = factory.factory

    if getattr(factory, '__name__', '').startswith('SimpleViewClass'):
        # In the case of a SimpleView, the base is really what we are
        # interested in. Usually the first listed class is the interesting one.
        base = factory.__bases__[0]
        info['path'] = base.__module__ + '.' + base.__name__
        info['template'] = relativizePath(factory.index.filename)
        info['template_obj'] = factory.index

    # Basic Type is a factory
    elif isinstance(factory, (six.string_types, float, int, list, tuple)):
        info['referencable'] = False

    elif factory.__module__ is not None:
        if factory.__module__.startswith(BROWSER_DIRECTIVES_MODULE):
            info['path'] = getPythonPath(factory.__bases__[0])
        # XML-RPC view factory, generated during registration
        elif (factory.__module__.startswith(XMLRPC_DIRECTIVES_MODULE)
            # JSON-RPC view factory, generated during registration
            # This is needed for the 3rd party jsonserver implementation
            # TODO: See issue http://www.zope.org/Collectors/Zope3-dev/504, ri
            or factory.__module__.startswith(JSONRPC_DIRECTIVES_MODULE)):
            # Those factories are method publisher and security wrapped
            info['path'] = getPythonPath(factory.__bases__[0].__bases__[0])

    if not info['path'] and not hasattr(factory, '__name__'):
        # A factory that is a class instance; since we cannot reference instances,
        # reference the class.
        info['path'] = getPythonPath(factory.__class__)

    if not info['path']:
        # Either a simple class-based factory, or not. It doesn't
        # matter. We have tried our best; just get the Python path as
        # good as you can.
        info['path'] = getPythonPath(factory)

    if info['referencable']:
        info['url'] = info['path'].replace('.', '/')

    if isinstance(factory, IconViewFactory):
        info['resource'] = factory.rname

    return info
Example #2
0
 def __init__(self, context, request):
     super(ModuleDetails, self).__init__(context, request)
     items = list(self.context.items())
     items.sort()
     self.text_files = []
     self.zcml_files = []
     self.modules = []
     self.interfaces = []
     self.classes = []
     self.functions = []
     for name, obj in items:
         entry = {'name': name, 'url': absoluteURL(obj, self.request)}
         if IFunctionDocumentation.providedBy(obj):
             entry['doc'] = formatDocString(
                 obj.getDocString(), self.context.getPath())
             entry['signature'] = obj.getSignature()
             self.functions.append(entry)
         elif IModuleDocumentation.providedBy(obj):
             entry['doc'] = formatDocString(
                 obj.getDocString(), obj.getPath(), True)
             self.modules.append(entry)
         elif IInterface.providedBy(obj):
             entry['path'] = getPythonPath(removeAllProxies(obj))
             entry['doc'] = formatDocString(
                 obj.__doc__, obj.__module__, True)
             self.interfaces.append(entry)
         elif IClassDocumentation.providedBy(obj):
             entry['doc'] = formatDocString(
                 obj.getDocString(), self.context.getPath(), True)
             self.classes.append(entry)
         elif IZCMLFile.providedBy(obj):
             self.zcml_files.append(entry)
         elif ITextFile.providedBy(obj):
             self.text_files.append(entry)
Example #3
0
def getViewInfoDictionary(reg):
    """Build up an information dictionary for a view registration."""
    # get configuration info
    if isinstance(reg.doc, (str, unicode)):
        doc = reg.doc
        zcml = None
    else:
        doc = None
        zcml = getParserInfoInfoDictionary(reg.doc)

    # get layer
    layer = None
    if ILayer.providedBy(reg.required[-1]):
        layer = getInterfaceInfoDictionary(reg.required[-1])


    info = {'name' : reg.name or '<i>no name</i>',
            'type' : getPythonPath(getPresentationType(reg.required[-1])),
            'factory' : getViewFactoryData(reg.value),
            'required': [getInterfaceInfoDictionary(iface)
                         for iface in reg.required],
            'provided' : getInterfaceInfoDictionary(reg.provided),
            'layer': layer,
            'doc': doc,
            'zcml': zcml
            }

    # Educated guess of the attribute name
    info.update(getPermissionIds('publishTraverse', klass=reg.value))

    return info
Example #4
0
 def _getInterfaceDetails(self, schema):
     schema = LocationProxy(schema,
                            self.context,
                            getPythonPath(schema))
     details = InterfaceDetails(schema, self.request)
     details._getFieldName = _getFieldName
     return details
Example #5
0
def getAdapterInfoDictionary(reg):
    """Return a PT-friendly info dictionary for an adapter registration."""
    factory = getRealFactory(reg.value)
    path = getPythonPath(factory)

    url = None
    if isReferencable(path):
        url = path.replace('.', '/')

    if isinstance(reg.doc, (str, unicode)):
        doc = reg.doc
        zcml = None
    else:
        doc = None
        zcml = getParserInfoInfoDictionary(reg.doc)

    return {
        'provided': getInterfaceInfoDictionary(reg.provided),
        'required': [getInterfaceInfoDictionary(iface)
                     for iface in reg.required
                     if iface is not None],
        'name': getattr(reg, 'name', _('<subscription>')),
        'factory': path,
        'factory_url': url,
        'doc': doc,
        'zcml': zcml}
 def getInterface(self):
     """Return the interface the utility provides."""
     schema = LocationProxy(self.context.interface,
                            self.context,
                            getPythonPath(self.context.interface))
     details = InterfaceDetails(schema, self.request)
     return details
def getAdapterInfoDictionary(reg):
    """Return a PT-friendly info dictionary for an adapter registration."""
    factory = getRealFactory(reg.factory)
    path = getPythonPath(factory)

    url = None
    if isReferencable(path):
        url = path.replace('.', '/')

    if isinstance(reg.info, six.string_types):
        doc = reg.info
        zcml = None
    else:
        doc = None
        zcml = getParserInfoInfoDictionary(reg.info)

    name = getattr(reg, 'name', u'')
    name = name.decode('utf-8') if isinstance(name, bytes) else name
    return {
        'provided': getInterfaceInfoDictionary(reg.provided),
        'required': [getSpecificationInfoDictionary(iface)
                     for iface in reg.required
                     if iface is not None],
        'name': name,
        'factory': path,
        'factory_url': url,
        'doc': doc,
        'zcml': zcml
    }
def getUtilityInfoDictionary(reg):
    """Return a PT-friendly info dictionary for a factory."""
    component = reg.component
    # Check whether we have an instance of some custom type or not
    # Unfortunately, a lot of utilities have a `__name__` attribute, so we
    # cannot simply check for its absence
    # TODO: Once we support passive display of instances, this insanity can go
    #       away.
    if not isinstance(component, (types.MethodType, types.FunctionType,
                                  six.class_types,
                                  InterfaceClass)):
        component = getattr(component, '__class__', component)

    path = getPythonPath(component)

    # provided interface id
    iface_id = '%s.%s' % (reg.provided.__module__, reg.provided.getName())

    # Determine the URL
    if isinstance(component, InterfaceClass):
        url = 'Interface/%s' % path
    else:
        url = None
        if isReferencable(path):
            url = 'Code/%s' % path.replace('.', '/')

    return {'name': six.text_type(reg.name) or _('<i>no name</i>'),
            'url_name': utilitymodule.encodeName(reg.name or '__noname__'),
            'iface_id': iface_id,
            'path': path,
            'url': url}
Example #9
0
 def getHandler(self):
     """Return information about the handler."""
     if self.context.handler is not None:
         path = getPythonPath(self.context.handler)
         return {
             'path': path,
             'url': isReferencable(path) and path.replace('.', '/') or None}
     return None
Example #10
0
 def getDirectlyProvidedInterfaces(self):
     # This comes from apidoc...
     # Getting the directly provided interfaces works only on naked objects
     naked = removeSecurityProxy(self.obj)
     return [
         utilities.getPythonPath(iface)
         for iface in zope.interface.directlyProvidedBy(naked)
     ]
Example #11
0
 def getModuleInterfaces(self):
     """Return entries about interfaces the module provides"""
     entries = []
     for iface in self.context.getDeclaration():
         entries.append({
             'name': iface.__name__,
             'path': getPythonPath(removeAllProxies(iface))
         })
     return entries
Example #12
0
 def getTypes(self):
     """Return a list of interface types that are specified for this
     interface."""
     # We have to really, really remove all proxies, since self.context (an
     # interface) is usually security proxied and location proxied. To get
     # the types, we need all proxies gone, otherwise the proxies'
     # interfaces are picked up as well.
     iface = removeAllProxies(self.context)
     return [{'name': type.getName(),
              'path': getPythonPath(type)}
             for type in interface.getInterfaceTypes(iface)]
Example #13
0
    def getEntries(self, columns=True):
        """Return info objects for all modules and classes in the
        associated apidoc container.

        """
        if (not hasattr(self.context, "apidoc")
                or not hasattr(self.context.apidoc, "items")):
            return None
        entries = []
        for name, obj in self.context.apidoc.items():
            entry = {
                'name': name,
                'obj': obj,
                'path': getPythonPath(removeAllProxies(obj)),
                'url': u'',
                'doc': None,
                'ispackage': False,
                'ismodule': False,
                'isinterface': False,
                'isclass': False,
                'isfunction': False,
                'istextfile': False,
                'iszcmlfile': False,
                'signature': None
            }
            entry['url'] = "%s/%s" % (self.context.path.replace('.',
                                                                '/'), name)
            if hasattr(obj, "getDocString"):
                entry['doc'] = self.getDocHeading(obj.getDocString())
            elif hasattr(obj, "getDoc") and isinstance(removeAllProxies(obj),
                                                       InterfaceClass):
                entry['doc'] = self.getDocHeading(obj.getDoc())
            if isinstance(obj, Class):
                entry['isclass'] = True
            elif isinstance(obj, TextFile):
                entry['istextfile'] = True
            elif isinstance(obj, ZCMLFile):
                entry['iszcmlfile'] = True
            elif isinstance(obj, Function):
                entry['isfunction'] = True
                if hasattr(obj, 'getSignature'):
                    entry['signature'] = obj.getSignature()
            elif (isinstance(obj, Module)
                  and os.path.basename(obj.getFileName())
                  in ['__init.py__', '__init__.pyc', '__init__.pyo']):
                entry['ispackage'] = True
            elif isinstance(obj, Module):
                entry['ismodule'] = True
            elif isinstance(obj, InterfaceClass):
                entry['isinterface'] = True
            entries.append(entry)

        entries.sort(lambda x, y: cmp(x['name'], y['name']))
        return entries
Example #14
0
    def items(self):
        sm = zapi.getSiteManager()
        ifaces = {}
        while sm is not None:
            for reg in sm.registrations():
                if isinstance(reg, UtilityRegistration):
                    path = getPythonPath(reg.provided)
                    ifaces[path] = UtilityInterface(self, path, reg.provided)
            sm = queryNextSiteManager(sm)

        items = ifaces.items()
        items.sort(lambda x, y: cmp(x[0].split('.')[-1], y[0].split('.')[-1]))
        return items
Example #15
0
    def getBases(self):
        """Get all bases of this class

        Example::

          >>> from tests import getInterfaceDetails
          >>> details = getInterfaceDetails()
          >>> details.getBases()
          ['zope.interface.Interface']
        """
        # Persistent interfaces are security proxied, so we need to strip the
        # security proxies off
        iface = removeSecurityProxy(self.context)
        return [getPythonPath(base) for base in iface.__bases__]
Example #16
0
def getFieldInfoDictionary(field, format=None):
    """Return a page-template-friendly information dictionary."""
    format = format or _getDocFormat(field)

    info = {'name': field.getName(),
            'required': field.required,
            'required_string': field.required and u'required' or u'optional',
            'default': repr(field.default),
            'title': field.title}

    # Determine the interface of the field
    iface = getFieldInterface(field)
    info['iface'] = {'name': iface.getName(), 'id': getPythonPath(iface)}

    # Determine the field class
    class_ = field.__class__
    info['class'] = {'name': class_.__name__,
                     'path': getPythonPath(class_).replace('.', '/')}

    # Render the field description
    info['description'] = renderText(field.description or u'', format=format)

    return info
Example #17
0
    def test__qualname__descriptor_path(self):
        # When the __qualname__ is not a string but a descriptor object,
        # getPythonPath does not raise an AttributeError
        # https://github.com/zopefoundation/zope.app.apidoc/issues/25

        from zope.app.apidoc.utilities import getPythonPath

        class O(object):
            "namespace object"

        o = O()
        o.__qualname__ = object()
        o.__name__ = 'foo'

        self.assertEqual('zope.app.apidoc.tests.foo', getPythonPath(o))
Example #18
0
 def getSubdirectives(self):
     """Create a list of subdirectives."""
     dirs = []
     for ns, name, schema, handler, info in self.context.subdirs:
         details = self._getInterfaceDetails(schema)
         path = getPythonPath(handler)
         url = isReferencable(path) and path.replace('.', '/') or None
         dirs.append({
             'namespace': ns,
             'name': name,
             'schema': details,
             'handler': {'path': path, 'url': url},
             'info': info,
             })
     return dirs
Example #19
0
 def _listClasses(self, classes):
     info = []
     for cls in classes:
         unwrapped_cls = removeAllProxies(cls)
         fullpath = getPythonPath(unwrapped_cls)
         if not fullpath:
             continue
         path, name = fullpath.rsplit('.', 1)
         info.append({
             'path': path or None,
             'path_parts': self.getPathParts(path) or None,
             'name': name,
             'url': fullpath and fullpath.replace('.', '/') or None,
             'doc': self.getDocHeading(cls.__doc__) or None
         })
     return info
def getFactoryInfoDictionary(reg):
    """Return a PT-friendly info dictionary for a factory."""
    factory = reg.component
    callable = factory

    # Usually only zope.component.factory.Factory instances have this attribute
    if IFactory.providedBy(factory) and hasattr(factory, '_callable'):
        callable = factory._callable
    elif hasattr(callable, '__class__'):
        callable = callable.__class__

    path = getPythonPath(callable)

    return {'name': six.text_type(reg.name) or _('<i>no name</i>'),
            'title': getattr(factory, 'title', u''),
            'description': renderText(getattr(factory, 'description', u''),
                                      module=callable.__module__),
            'url': isReferencable(path) and path.replace('.', '/') or None}
Example #21
0
 def getEntries(self, columns=True):
     """Return info objects for all modules and classes in this module."""
     entries = [{'name': name,
                 # only for interfaces; should be done differently somewhen
                 'path': getPythonPath(removeAllProxies(obj)),
                 'url': zapi.absoluteURL(obj, self.request),
                 'ismodule': zapi.isinstance(obj, Module),
                 'isinterface': zapi.isinstance(
                      removeAllProxies(obj), InterfaceClass),
                 'isclass': zapi.isinstance(obj, Class),
                 'isfunction': zapi.isinstance(obj, Function),
                 'istextfile': zapi.isinstance(obj, TextFile),
                 'iszcmlfile': zapi.isinstance(obj, ZCMLFile)}
                for name, obj in self.context.items()]
     entries.sort(lambda x, y: cmp(x['name'], y['name']))
     if columns:
         entries = columnize(entries)
     return entries
Example #22
0
    def objectURL(self, value, field, rootURL):
        naked = removeSecurityProxy(self.context)
        bound = field.bind(naked.context)
        obj = bound.fromUnicode(value)
        if obj is None:
            return
        try:
            isInterface = IInterface.providedBy(obj)
        except AttributeError:
            # probably an object that does not like to play nice with the CA
            isInterface = False

        # The object mught be an instance; in this case get a link to the class
        if not hasattr(obj, '__name__'):
            obj = getattr(obj, '__class__')
        path = getPythonPath(obj)
        if isInterface:
            return rootURL+'/../Interface/%s/index.html' % path
        if isReferencable(path):
            return rootURL + '/%s/index.html' %(path.replace('.', '/'))
Example #23
0
 def _listClasses(self, classes):
     """Prepare a list of classes for presentation."""
     info = []
     codeModule = zapi.getUtility(IDocumentationModule, "Code")
     for cls in classes:
         # We need to removeAllProxies because the security checkers for
         # zope.app.container.contained.ContainedProxy and
         # zope.app.i18n.messagecatalog.MessageCatalog prevent us from
         # accessing __name__ and __module__.
         unwrapped_cls = removeAllProxies(cls)
         path = getPythonPath(unwrapped_cls)
         url = None
         try:
             klass = zapi.traverse(codeModule, path.replace('.', '/'))
             url = zapi.absoluteURL(klass, self.request)
         except TraversalError:
             # If one of the classes is implemented in C, we will not
             # be able to find it.
             pass
         info.append({'path': path or None, 'url': url})
     return info
    def items(self):
        # Use a list of site managers, since we want to support multiple bases
        smlist = [zope.component.getSiteManager()]
        seen = []
        ifaces = {}
        while smlist:
            # Get the next site manager
            sm = smlist.pop()
            # If we have already looked at this site manager, then skip it
            if sm in seen: # pragma: no cover
                continue
            # Add the current site manager to the list of seen ones
            seen.append(sm)
            # Add the bases of the current site manager to the list of site
            # managers to be processed
            smlist += list(sm.__bases__)
            for reg in sm.registeredUtilities():
                path = getPythonPath(reg.provided)
                ifaces[path] = UtilityInterface(self, path, reg.provided)

        items = sorted(ifaces.items(),
                       key=lambda x: x[0].split('.')[-1])
        return items
def getViewInfoDictionary(reg):
    """Build up an information dictionary for a view registration."""
    # get configuration info
    if isinstance(reg.info, six.string_types):
        doc = reg.info
        zcml = None
    else:
        doc = None
        zcml = getParserInfoInfoDictionary(reg.info)

    info = {'name' : six.text_type(reg.name) or _('<i>no name</i>'),
            'type' : getPythonPath(getPresentationType(reg.required[-1])),
            'factory' : getViewFactoryData(reg.factory),
            'required': [getInterfaceInfoDictionary(iface)
                         for iface in reg.required],
            'provided' : getInterfaceInfoDictionary(reg.provided),
            'doc': doc,
            'zcml': zcml
            }

    # Educated guess of the attribute name
    info.update(getPermissionIds('publishTraverse', klass=reg.factory))

    return info
def getTypeInfoDictionary(type):
    """Return a PT-friendly info dictionary for a type."""
    path = getPythonPath(type)
    return {'name': type.__name__,
            'module': type.__module__,
            'url': isReferencable(path) and path.replace('.', '/') or None}
Example #27
0
def getInterfaceInfo(iface):
    if iface is None:
        return None
    path = getPythonPath(iface)
    return {'path': path,
            'url': isReferencable(path) and path or None}
Example #28
0
def getTypeLink(type):
    if type is types.NoneType:
        return None
    path = getPythonPath(type)
    return isReferencable(path) and path.replace('.', '/') or None
Example #29
0
def getInterfaceInfo(iface):
    if iface is None:
        return None
    path = getPythonPath(iface)
    return {'path': path, 'url': isReferencable(path) and path or None}
Example #30
0
 def getTypeLink(self, obj_type):
     if obj_type is types.NoneType:
         return None
     path = utilities.getPythonPath(obj_type)
     return path.replace('.', '/')
Example #31
0
 def getPythonPath(self):
     return utilities.getPythonPath(self.obj)