[Checkins] SVN: grokui.admin/branches/introspectorless/src/grokui/admin/ Removed grokdoc and introspecting methods and views. Started to remove the apidoc dependencies. Still need to clean the imports and then the dependencies. Still needs work on the application description. Tests needs to be cleaned heavily too.

Souheil CHELFOUH souheil at chelfouh.com
Mon Sep 14 18:26:34 EDT 2009


Log message for revision 103985:
  Removed grokdoc and introspecting methods and views. Started to remove the apidoc dependencies. Still need to clean the imports and then the dependencies. Still needs work on the application description. Tests needs to be cleaned heavily too.

Changed:
  U   grokui.admin/branches/introspectorless/src/grokui/admin/__init__.py
  D   grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.py
  D   grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.txt
  D   grokui.admin/branches/introspectorless/src/grokui/admin/inspect.txt
  D   grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.py
  D   grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.txt
  U   grokui.admin/branches/introspectorless/src/grokui/admin/security.py
  U   grokui.admin/branches/introspectorless/src/grokui/admin/static/grok.css
  U   grokui.admin/branches/introspectorless/src/grokui/admin/utilities.py
  U   grokui.admin/branches/introspectorless/src/grokui/admin/view.py
  U   grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/applications.pt
  U   grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/grokadminmacros.pt

-=-
Modified: grokui.admin/branches/introspectorless/src/grokui/admin/__init__.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/__init__.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/__init__.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -13,3 +13,10 @@
 ##############################################################################
 # a package
 __import__('pkg_resources').declare_namespace(__name__)
+
+
+import grok
+
+class Test(grok.Container, grok.Application):
+    """test
+    """

Deleted: grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,657 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation 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.
-#
-##############################################################################
-"""The Grok's Friendly Doctor.
-
-Ask DocGrok and he will try his best, to keep you well informed about
-everything hanging around in your Zope3 and your Grok Application.
-
-See file `docgrok.txt` in this package to learn more about docgrok.
-
-"""
-
-import os
-import sys # for sys.path
-import types
-import martian
-import grok
-import inspect
-from urlparse import urlparse, urlunparse
-
-import zope.component
-from zope.app.folder.interfaces import IRootFolder
-from zope.dottedname.resolve import resolve
-from zope.interface.interface import InterfaceClass
-from zope.security.proxy import isinstance
-from zope.security.proxy import removeSecurityProxy
-from zope.proxy import removeAllProxies
-
-from zope.app.apidoc.codemodule.module import Module
-from zope.app.apidoc.codemodule.class_ import Class
-from zope.app.apidoc.codemodule.text import TextFile
-from zope.app.apidoc.utilities import renderText
-from zope.app.apidoc.utilities import getFunctionSignature
-from zope.app.apidoc.utilities import getPythonPath, getPermissionIds
-from zope.app.apidoc.utilities import isReferencable
-
-import grok.interfaces
-from grok.interfaces import IApplication
-from martian.scan import is_package, ModuleInfo
-from martian import ClassGrokker, ModuleGrokker
-from grokui.admin.objectinfo import ZopeObjectInfo
-
-# This is the name under which the docgrok object-browser can be
-# reached.
-DOCGROK_ITEM_NAMESPACE = 'docgrok-obj'
-
-grok.context(IRootFolder)
-
-def find_filepath(dotted_path):
-    """Find the filepath for a dotted name.
-
-    If a dotted name denotes a filename we try to find its path
-    by concatenating it with the system paths and looking for an
-    existing file. Every dot in the filename thereby can be part
-    of the filename or of its path. Therefore we check the
-    several possible dirname/filename combinations possible.
-
-    Returns None if no suitable filepath can be found.
-
-    This functions does *not* look for Python elements like classes,
-    interfaces and the files where they were defined. Use `resolve()`
-    and the `__file__` attribute for examining this kind of stuff
-    instead.
-
-    This function finds the location of text files and the like, as
-    far as they are placed inside some Python path.
-    """
-    currpath = dotted_path
-    currname = ""
-    while '.' in currpath:
-        currpath, name = currpath.rsplit('.', 1)
-        if currname != "":
-            currname = "." + currname
-        currname = name + currname
-        tmp_path = ""
-        for elem in currpath.split('.'):
-            tmp_path = os.path.join(tmp_path, elem)
-        for syspath in sys.path:
-            filepath_to_check = os.path.join(syspath, tmp_path, currname)
-            if os.path.isfile(filepath_to_check):
-                return filepath_to_check
-    return None
-
-class DocGrokHandler(object):
-    """A handler for DocGrok objects.
-
-    The solely purpose of DocGrokHandlers is to determine, whether a
-    given dotted path denotes a special type of object. If so, it
-    should pass back an appropriate DocGrok object.
-
-    In plain English: DocGrokHandlers find a doctor for any object.
-
-    All we expect a DocGrokHandler to support, is a method
-    ``getDoctor``, which takes a dotted path (and optional the object
-    denoted by this path), to deliver an appropriate doctor or
-    ``None``.
-    """
-    def getDoctor(self, dotted_path, obj=None):
-        """The default docfinder cannot serve.
-        """
-        return
-
-
-class DocGrokModuleHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Find a doctor for modules or None, if the dotted_path does
-        not denote a module.
-        """
-        if obj is None:
-            try:
-                obj = resolve(dotted_path)
-            except ImportError:
-                return
-        if not hasattr(obj, '__file__'):
-            return
-        if not is_package(os.path.dirname(obj.__file__)):
-            return
-        if os.path.basename(obj.__file__) in ['__init__.py',
-                                             '__init__.pyc',
-                                             '__init__.pyo']:
-            return
-        return DocGrokModule(dotted_path)
-
-
-class DocGrokPackageHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Determine, whether the given path/obj references a Python
-        package.
-        """
-        if obj is None:
-            try:
-                obj = resolve(dotted_path)
-            except ImportError:
-                return
-        if not hasattr(obj, '__file__'):
-            return
-        if not is_package(os.path.dirname(obj.__file__)):
-            return
-        if os.path.basename(obj.__file__) not in ['__init__.py',
-                                                 '__init__.pyc',
-                                                 '__init__.pyo']:
-            return
-        return DocGrokPackage(dotted_path)
-
-
-class DocGrokInterfaceHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Determine, whether the given path/obj references an interface.
-        """
-        if obj is None:
-            try:
-                obj = resolve(dotted_path)
-            except ImportError:
-                return
-        if not isinstance(
-            removeAllProxies(obj), InterfaceClass):
-            return
-        return DocGrokInterface(dotted_path)
-
-
-class DocGrokClassHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Determine, whether the given path/obj references a Python class.
-        """
-        if obj is None:
-            try:
-                obj = resolve(dotted_path)
-            except ImportError:
-                return
-        if not isinstance(obj, (types.ClassType, type)):
-            return
-        return DocGrokClass(dotted_path)
-
-
-class DocGrokGrokApplicationHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Determine, whether the given path/obj references a Grok application.
-        """
-        if obj is None:
-            try:
-                obj = resolve(dotted_path)
-            except ImportError:
-                None
-        try:
-            if not IApplication.implementedBy(obj):
-                return
-        except TypeError:
-            return
-        return DocGrokGrokApplication(dotted_path)
-
-
-class DocGrokTextFileHandler(DocGrokHandler):
-    def getDoctor(self, dotted_path, obj=None):
-        """Determine whether the dotted_path denotes a textfile.
-        """
-        if obj is not None:
-            # Textfiles that are objects, are not text files.
-            return
-        if os.path.splitext(dotted_path)[1] != u'.txt':
-            return
-        return DocGrokTextFile(dotted_path)
-
-
-def docgrok_handle(dotted_path):
-    """Find a doctor specialized for certain things.
-    """
-    try:
-        ob = resolve(dotted_path)
-    except ImportError:
-        # There is no object of that name. Give back 404.
-        # TODO: Do something more intelligent, offer a search.
-        if not find_filepath(dotted_path):
-            return
-        ob = None
-    except:
-        return
-
-    for handler in docgrok_handlers:
-        if type(handler) is not type({}):
-            continue
-        if 'docgrok_handler' not in handler.keys():
-            continue
-        spec_handler = handler['docgrok_handler']()
-        if not isinstance(spec_handler, DocGrokHandler):
-            continue
-        doc_grok = spec_handler.getDoctor(dotted_path, ob)
-        if doc_grok is None:
-            continue
-        return doc_grok
-    # No special doctor could be found.
-    return DocGrok(dotted_path)
-
-def getInterfaceInfo(iface):
-    if iface is None:
-        return
-    path = getPythonPath(iface)
-    return {'path': path,
-            'url': isReferencable(path) and path or None}
-
-
-class DocGrokGrokker(ClassGrokker):
-    """A grokker that groks DocGroks.
-
-    This grokker can help to 'plugin' different docgroks in an easy
-    way. You can register docgroks for your special classes, modules,
-    things. All required, is a function, that determines the correct
-    kind of thing, you like to offer a docgrok for and returns a
-    specialized docgrok or None (in case the thing examined is not the
-    kind of thing your docgrok is a specialist for).
-
-    Unfortunately, order counts here. If one docgrok handler is able
-    to deliver a specialized docgrok object, no further invesitgation
-    will be done.
-
-    In principle, the following should work. First we import the
-    docgrok module, because it contains a more specific grokker: the
-    InstanceGrokker 'docgrok_grokker' ::
-
-      >>> from grokui.admin import docgrok
-
-    Then we create an (empty) 'ModuleGrokker'. 'ModuleGrokkers' can
-    grok whole modules. ::
-
-      >>> from martian import ModuleGrokker
-      >>> module_grokker = ModuleGrokker()
-
-    Then we register the 'docgrok_grokker', which should contain some
-    base handlers for modules, classes, etc. by default::
-
-      >>> module_grokker.register(docgrok.docgrok_handler_grokker)
-
-    The 'docgrok_handler_grokker' is an instance of 'DocGrokGrokker'::
-
-      >>> from grokui.admin.docgrok import DocGrokGrokker
-      >>> isinstance(docgrok.docgrok_handler_grokker, DocGrokGrokker)
-      True
-
-    That's it.
-
-    """
-    martian.component(DocGrokHandler)
-
-    def execute(self, name, obj, **kw):
-        return self.grok(name, obj, **kw)
-
-    def grok(self, name, obj, **kw):
-        if not issubclass(obj, DocGrokHandler):
-            return
-        if not hasattr(obj, 'getDoctor'):
-            return
-        docgrok_handlers.insert(0, {'name':name,
-                                    'docgrok_handler':obj})
-        return True
-
-
-class DocGrok(grok.Model):
-    """DocGrok helps us finding out things about ourselves.
-
-    There are DocGroks for packages, modules, interfaces, etc., each
-    one a specialist for a certain type of element. 'Pure' DocGroks
-    build the root of this specialist hierarchy and care for objects,
-    which can not be handled by other, more specialized DocGroks.
-
-    DocGrok offers a minimum of information but can easily be extended in
-    derived classes.
-    """
-    path = None
-    _traversal_root = None
-
-    def __init__(self, dotted_path):
-        self.path = dotted_path
-
-    def getPath(self):
-        return self.path
-
-    def getFilePath(self):
-        try:
-            ob = resolve(self.path)
-            return hasattr(ob, __file__) and os.path.dirname(ob.__file__) or None
-        except ImportError:
-            pass
-        return find_filepath(self.path)
-
-    def getDoc(self, heading_only=False):
-        """Get the doc string of the module STX formatted.
-        """
-        if hasattr(self, "apidoc") and hasattr(
-            self.apidoc, "getDocString"):
-            text = self.apidoc.getDocString()
-        else:
-            return
-        if text is None:
-            return
-        lines = text.strip().split('\n')
-        if len(lines) and heading_only:
-            # Find first empty line to separate heading from trailing text.
-            headlines = []
-            for line in lines:
-                if line.strip() == "":
-                    break
-                headlines.append(line)
-            lines = headlines
-        # Get rid of possible CVS id.
-        lines = [line for line in lines if not line.startswith('$Id')]
-        return renderText('\n'.join(lines), self.path)
-
-
-    def traverse(self,patient):
-        """ Do special traversing inside the surgery.
-
-        Inside the docgrok-'namespace' we only accept DocGroks and
-        colleagues. Each DocGrok cares for a patient represented by a
-        path. This path might denote an object in the ZODB or in the
-        python path.
-
-        """
-        if patient == "index.html":
-            return self
-        if self.path is None:
-            newpath = patient
-        else:
-            newpath = '.'.join([self.path, patient])
-
-        doctor = docgrok_handle(newpath)
-
-        if doctor is None:
-            # There is nothing of that name. Give back 404.
-            # XXX Do something more intelligent, offer a search.
-            return
-        doctor.__parent__ = self
-        doctor.__name__ = patient
-        doctor._traversal_root = self._traversal_root
-        doctor.path = newpath
-        return doctor
-    pass
-
-def getItemLink(name, baseurl):
-    """Get a link to a docgrok item out of an item name and a base URL.
-
-    A docgrok item is any object, which is a 'subobject' of another
-    object, for example an attribute, a memberfunction, an annotation
-    or a sequence item (if the parent object is a sequence). Those
-    objects are not neccessarily directly accessible, but need to be
-    denoted for the object browser. We put 'docgrok-item' as marker at
-    the beginning of the URL to enable the docgrok traverser and to
-    handle those URLs in a special way. Such the objectbrowser can
-    handle those 'unaccessible' items.
-    """
-    url = list(urlparse(baseurl))
-    path = url[2]
-    if path.startswith('/' + DOCGROK_ITEM_NAMESPACE + '/'):
-        path = path[len(DOCGROK_ITEM_NAMESPACE) + 2:]
-    if path.endswith('/@@inspect.html') or path.endswith('/inspect.html'):
-        path = path.rsplit('/', 1)
-    path = "/%s/%s%s/@@inspect.html" % (DOCGROK_ITEM_NAMESPACE, path, name)
-    path = path.replace('//', '/')
-    url[2] = path
-    return urlunparse(url)
-
-
-class DocGrokTraverser(grok.Traverser):
-    """If first URL element is 'docgrok', handle over to DocGrok.
-
-    This traverser binds to the RootFolder, which means, it is only
-    asked, when the publisher looks for elements in the Zope root (or
-    another IRootFolder). The further traversing is done by the Docs'
-    own traverser in it's model. See method `traverse()` in DocGrok.
-    """
-    grok.context(IRootFolder)
-
-    def traverse(self,path):
-        if path == DOCGROK_ITEM_NAMESPACE:
-            # The objectbrowser is called...
-            obj_info = ZopeObjectInfo(self.context)
-            obj_info.__parent__ = self.context
-            obj_info.__name__ = DOCGROK_ITEM_NAMESPACE
-            return obj_info
-
-        if path == "docgrok":
-            doctor = DocGrok(None)
-            # Giving a __parent__ and a __name__, we make things
-            # locatable in sense of ILocatable.
-            doctor.__parent__ = self.context
-            doctor.__name__ = 'docgrok'
-            doctor._traversal_root = doctor
-            return doctor
-        return
-
-
-class DocGrokPackage(DocGrok):
-    """This doctor cares for python packages.
-    """
-    path=None
-    apidoc = None
-    _traversal_root = None
-
-    def __init__(self,dotted_path):
-        self.path = dotted_path
-        self._module = resolve(self.path)
-        # In apidoc packages are handled like modules...
-        self.apidoc = Module(None, None, self._module, True)
-
-    def getDocString(self):
-        return self.apidoc.getDocString()
-
-    def getFilePath(self):
-        ob = resolve(self.path)
-        return os.path.dirname(ob.__file__) + '/'
-
-    def _getModuleInfos(self, filter_func=lambda x:x):
-        """Get modules and packages of a package.
-
-        The filter function will be applied to a list of modules and
-        packages of type grok.scan.ModuleInfo.
-        """
-        ob = resolve(self.path)
-        filename = ob.__file__
-        module_info = ModuleInfo(filename, self.path)
-        try:
-            infos = module_info.getSubModuleInfos(exclude_tests=False)
-        except TypeError:
-            # Another version of martian.scan is installed
-            infos = module_info.getSubModuleInfos()
-        if filter_func is not None:
-            infos = filter(filter_func, infos)
-        result = []
-        for info in infos:
-            subresult = {}
-            # Build a url string from dotted path...
-            mod_path = "docgrok"
-            for path_part in info.dotted_name.split('.'):
-                mod_path = os.path.join(mod_path, path_part)
-            subresult = {
-                'url' : mod_path,
-                'name' : info.name,
-                'dotted_name' : info.dotted_name
-                }
-            result.append(subresult)
-        return result
-
-
-    def getModuleInfos(self):
-        """Get the modules inside a package.
-        """
-        filter_func = lambda x: not x.isPackage()
-        return self._getModuleInfos(filter_func)
-
-    def getSubPackageInfos(self):
-        """Get the subpackages inside a package.
-        """
-        filter_func = lambda x: x.isPackage()
-        return self._getModuleInfos(filter_func)
-
-    def getTextFiles(self):
-        """Get the text files inside a package.
-        """
-        filter_func = lambda x: x.isinstance(TextFile)
-        return self._getModuleInfos(filter_func)
-
-    def getChildren(self):
-        result = self.apidoc.items()
-        result.sort(lambda x,y:cmp(x[0], y[0]))
-        return result
-
-
-
-class DocGrokModule(DocGrokPackage):
-    """This doctor cares for python modules.
-    """
-
-    def getFilePath(self):
-        ob = resolve(self.path)
-        filename = ob.__file__
-        if filename.endswith('o') or filename.endswith('c'):
-            filename = filename[:-1]
-        return filename
-
-
-class DocGrokClass(DocGrokPackage):
-    """This doctor cares for classes.
-    """
-    def __init__(self,dotted_path):
-        self.path = dotted_path
-        self.klass = resolve(self.path)
-        self.module_path, self.name = dotted_path.rsplit('.',1)
-        self.module = resolve(self.module_path)
-        mod_apidoc = Module(None, None, self.module, False)
-        self.apidoc = Class(mod_apidoc, self.name, self.klass)
-
-    def getFilePath(self):
-        if not hasattr(self.module, "__file__"):
-            return
-        filename = self.module.__file__
-        if filename.endswith('o') or filename.endswith('c'):
-            filename = filename[:-1]
-        return filename
-
-    def getAttributes(self):
-        """Get the attributes of this class."""
-        attrs = []
-        # See remark in getMethods()
-        klass = removeSecurityProxy(self.apidoc)
-        for name, attr, iface in klass.getAttributes():
-            entry = {'name': name,
-                     'value': `attr`,
-                     'type': type(attr).__name__,
-                     'interface': iface
-                }
-            entry.update(getPermissionIds(name,klass.getSecurityChecker()))
-            attrs.append(entry)
-        return attrs
-
-    def getMethods(self):
-        """Get all methods of this class."""
-        methods = []
-        # remove the security proxy, so that `attr` is not proxied. We could
-        # unproxy `attr` for each turn, but that would be less efficient.
-        #
-        # `getPermissionIds()` also expects the class's security checker not
-        # to be proxied.
-        klass = removeSecurityProxy(self.apidoc)
-        for name, attr, iface in klass.getMethodDescriptors():
-            entry = {'name': name,
-                     'signature': "(...)",
-                     'doc':attr.__doc__ or '',
-                     'attr' : attr,
-                     'interface' : iface}
-            entry.update(getPermissionIds(name, klass.getSecurityChecker()))
-            methods.append(entry)
-
-        for name, attr, iface in klass.getMethods():
-            entry = {'name': name,
-                     'signature': getFunctionSignature(attr),
-                     'doc':attr.__doc__ or '',
-                     'attr' : attr,
-                     'interface' : iface}
-            entry.update(getPermissionIds(name, klass.getSecurityChecker()))
-            methods.append(entry)
-        return methods
-
-
-class DocGrokInterface(DocGrokClass):
-    """This doctor cares for interfaces.
-    """
-    def __init__(self,dotted_path):
-        self.path = dotted_path
-        self.klass = resolve(self.path)
-        self.module_path, self.name = dotted_path.rsplit('.',1)
-        self.module = resolve(self.module_path)
-        mod_apidoc = Module(None, None, self.module, False)
-        self.apidoc = Class(mod_apidoc, self.name, self.klass)
-
-    def getFilePath(self):
-        if not hasattr(self.module, "__file__"):
-            return
-        filename = self.module.__file__
-        if filename.endswith('o') or filename.endswith('c'):
-            filename = filename[:-1]
-        return filename
-
-class DocGrokGrokApplication(DocGrokClass):
-    """This doctor cares for Grok applications and components.
-    """
-    pass
-
-class DocGrokTextFile(DocGrok):
-    """This doctor cares for text files.
-    """
-
-    def __init__(self,dotted_path):
-        self.path = dotted_path
-        self.filepath = find_filepath(self.path)
-        self.filename = os.path.basename(self.filepath)
-
-
-    def getPackagePath(self):
-        """Return package path as dotted name.
-        """
-        dot_num_in_filename = len([x for x in self.filename if x == '.'])
-        parts = self.path.rsplit('.', dot_num_in_filename + 1)
-        return parts[0]
-
-    def getContent(self):
-        """Get file content UTF-8 encoded.
-        """
-        file = open(self.filepath, 'rU')
-        content = file.read()
-        file.close()
-        return content.decode('utf-8')
-
-# The docgroks registry.
-#
-# We register 'manually', because the handlers
-# are defined in the same module.
-docgrok_handlers = []
-
-docgrok_handler_grokker = DocGrokGrokker()
-docgrok_handler_grokker.grok('module', DocGrokModuleHandler)
-docgrok_handler_grokker.grok('package', DocGrokPackageHandler)
-docgrok_handler_grokker.grok('interface', DocGrokInterfaceHandler)
-docgrok_handler_grokker.grok('class', DocGrokClassHandler)
-docgrok_handler_grokker.grok('grokapplication',
-                             DocGrokGrokApplicationHandler)
-docgrok_handler_grokker.grok('textfile', DocGrokTextFileHandler)
-docgrok_handlers_grokker = ModuleGrokker()
-docgrok_handlers_grokker.register(docgrok_handler_grokker)
-

Deleted: grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.txt
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.txt	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/docgrok.txt	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,291 +0,0 @@
-=======
-DocGrok
-=======
-
-The Grok's personal doctor.
-
-DocGrok is meant as a friendly extension of the Zope 3 'builtin'
-apidoc feature. It should be easy to handle and informative in
-content. Main target are developers new to Grok.
-
-DocGrok is a helper to generate documentation for nearly everything
-living in a running Zope 3 instance. Basically it provides
-'information'-objects for different types of things, like modules,
-classes, functions, textfiles etc.
-
-A ``DocGrok`` therefore is an object wich normally is bound to a
-certain entity, which is describable by a dotted path. It provides
-special methods to get information about the thing, a certain
-``DocGrok`` is bound to.
-
-.. contents::
-
-
-How to Use it
--------------
-
-DocGrok documentation can be accessed through the web, calling special
-URL paths in your Zope 3 instance or (surprise!) directly via Python.
-
-
-Calling DocGrok through the web
-+++++++++++++++++++++++++++++++
-
-To get documentation about a special element, call docgrok simply with
-`docgrok` as first part of the URL path.
-
-For example documentation about the grok package can be reached using
-
-    http://localhost:8080/docgrok/grok
-
-The admin package can be accessed directly such:
-
-    http://localhost:8080/docgrok/grokui/admin
-
-In this way nearly all things can be described, which can be described
-by a dotted name notation and which are accessible at runtime.
-
-
-Calling the doctor directly
-+++++++++++++++++++++++++++
-
-The doctor can also be reached via Python, naturally:
-
-   >>> import grok
-   >>> from grokui.admin import docgrok
-   >>> doctor = docgrok.DocGrok('grokui.admin.docgrok')
-
-This doctor has immediatly a patient, which is denoted by the dotted
-path `grokui.admin.docgrok`. The dotted path might reference any thing
-which lives in the Python environment: a package, a module, a class, a
-function or even a file or some interface attribute:
-
-   >>> doctor.getPath()
-   'grokui.admin.docgrok'
-
-We can also get a filepath, using the `getFilePath()` method. Objects,
-which have no filepath always return `None`.
-
-There is not much more information to get from Doc Grok. This is,
-because a `DocGrok` only knows very little about the objects. The base
-doc is not a specialist, but cares for all objects and elements, which
-can not be handled by other specialists.
-
-If we like to get more detailed information, we have to call a
-specialist. For example a package doctor, who happens to be called
-`DocGrokPackage` :
-
-    >>> from grokui.admin.docgrok import DocGrokPackage
-    >>> doctor = DocGrokPackage('grok')
-    >>> doctor
-    <grokui.admin.docgrok.DocGrokPackage ...>
-
-Using ``getPath()`` we get the dotted path of the thing, the doctor
-cares for:
-
-    >>> doctor.getPath()
-    'grok'
-
-Fine. Obviously DocGrokPackages know as much as DocGroks. That's
-little. But a ``DocGrokPackage`` knows also about package-things:
-
-    >>> info = doctor.getSubPackageInfos()
-
-will generate infos subpackages contained in the package we are
-examining. The ``info`` here is basically a list of dictionaries,
-where each dictionary contains a the keys ``url``, ``name`` and
-``dotted_name``:
-
-    >>> info
-    [{'url': '...', 'dotted_name': '...', 'name': '...'}...]
-
-The ``url`` element is meant as the path 'inside' the
-``docgrok``-browser, when ``docgrok`` documentation is watched in a
-browser. ``dotted_name`` and ``name`` give the dotted path of a
-subpackage and last element of this path respectively.
-
-As said, ``DocGrokPackage`` is only one possible type of 'documenter'
-already included in the docgrok module. The different ``DocGroks``
-included are documented below in section `the specialists`_ in detail.
-
-So, this is allright if we already know, what kind of thing (a module,
-package, etc.) the doctor should examine. Then we can create an
-appropriate doctor and retrieve all information we like.
-
-But how can we find out, what kind of thing we examine? Shouldn't this
-be a doctors job as well? Right! This is possible and you should *use*
-the possibility to determine the most appropriate doctor
-automatically.
-
-
-Getting the right specialist directly
-+++++++++++++++++++++++++++++++++++++
-
-Often we don't want to visit the base doctor, but a specialist
-directly. But how can we tell, what specialist we need? Easy. We use
-the function ``docgrok_handle()`` which delivers us a doctor, who
-can tell us more:
-
-    >>> from grokui.admin.docgrok import docgrok_handle
-    >>> thedoc = docgrok_handle('grokui.admin.docgrok')
-    >>> thedoc
-    <grokui.admin.docgrok.DocGrokModule ...>
-
-This is correct. `docgrok` of course *is* a python module, so the best
-specialist we can get is a `DocGrokModule`. The mentioned function
-therefore is some kind of factory, which always gives us a doctor most
-appropriate for the kind of thing specified by a dotted path.
-
-We can, for example ask for a different doc like this:
-
-    >>> thedoc = docgrok_handle('grokui.admin.docgrok.DocGrok')
-    >>> thedoc
-    <grokui.admin.docgrok.DocGrokClass ...>
-
-and get a class-specific doctor. Because
-``grokui.admin.docgrok.DocGrok`` *is* a class, this is again the most
-appropriate doc we could get.
-
-
-How to create your own specialist docgrok
------------------------------------------
-
-At times you might want to create your own sort of DocGrok. This might
-be due to the fact, that you have written a special kind of 'thing' (a
-special class, module, whatever), whose special attributes, methods,
-etc. should be made available in documentation in a special way.
-
-Thanks to Martijn Faassens ``martian`` package, this can be done very
-easily. All you need is a handler function, which is able to determine
-from a dotted path, whether some 'thing' is of the type you want
-special documentation for, and, of course, a special docgrok, which is
-able to deliver the special information about your new 'thing'.
-
-Let's see how this works.
-
-Writing new DocGroks
-++++++++++++++++++++
-
-Consider we want to document ``grok.View`` classes. Since
-``grok.View`` is a class, we choose the DocGrokClass as base for our
-new DocGrok:
-
-    >>> from grokui.admin.docgrok import DocGrokClass
-
-    >>> class DocGrokGrokView(DocGrokClass):
-    ...     """"This doctor cares for grok.Views."""
-    ...     pass
-
-Now we create a doctor:
-
-    >>> doctor = DocGrokGrokView()
-    Traceback (most recent call last):
-        [...]
-    TypeError: __init__() takes exactly 2 arguments (1 given)
-
-Oops! Well, we didn't specify, what kind of DocGrokView we want to
-examine. We can do that, giving a dotted name:
-
-    >>> doctor = DocGrokGrokView('grok.View')
-    >>> doctor
-    <DocGrokGrokView ...>
-
-The doctor is in. Fine. So let's see, what he can tell us about
-``grok.View``.
-
-    >>> doctor.getPath()
-    'grok.View'
-
-Ah, yes, very interesting. We got the dotted path of the examined
-class. But, where can we find the definition of it in file system? Ask
-the doc:
-
-    >>> pnorm(doctor.getFilePath())
-    '.../grok/__init__.py'
-
-This is not exactly, what we wanted to know, is it? We got the package
-location instead of the module. So the path is wrong. Really? When you
-have a look at the specified ``__init__.py``, you will discover, that
-there is indeed an assignment, which says, that ``grok.View`` is
-another name for ``grok.components.View``. It is simply a shortcut. So,
-as we asked for ``grok.View`` the answer was correct.
-
-To check it, let's see, what happens, if we give the real dotted path:
-
-    >>> doctor = DocGrokGrokView('grok.components.View')
-    >>> pnorm(doctor.getFilePath())
-    '.../grok/components.py'
-
-Ah, right. This is, what we wanted. Now we can use some of the derived
-methods to gather some more information about this class:
-
-    >>> methods = doctor.getMethods()
-
-delivers us a list of all public methods defined in this class. Each
-list entry being a dictionary with keys ``name``, ``signature``,
-``doc``, ``interface``, ``attr``, ``read_perm`` and `` write_perm``.
-
-    >>> entry = [x for x in methods if x['name'] == 'url'][0]
-    >>> entry['name']
-    'url'
-    >>> print entry['doc'].strip()
-    Return string for the URL based on the obj and name. The data
-    argument is used to form a CGI query string.
-    >>> entry['signature']
-    '(obj=None, name=None, data=None)'
-
-The other methods work as described in the ``DocGrokClass``
-documentation.
-
-This is all very well, but not too impressive. We could gather the
-information delivered relatively easy writing some simple
-snippets. So, what is it all about?
-
-One main reason is, that ``DocGroks`` are used by the Grok admin
-interface to provide easy accessible API documentation. Those
-documentation is basically able, to give some information about
-everything, which is describable as a dotted path. But some of the
-information is not very descriptive. That's it, why ``docgrok`` uses a
-set of helpers, to give more detailed information. If you, for
-instance, want that instead of the standard class-related docgrok your
-own docgrok is displayed, whenever a user wants to know something
-about ``grok.View`` and related classes, then you can register your
-docgrok and let it display documentation for ``grok.View``.
-
-The selection to register a docgrok for ``grok.View`` was very
-arbitrary. You can also register a docgrok, that handles all elements,
-whose name starts with the letter 'a' or those elements, which are
-classes and implement at least three different interfaces. It's
-completely up to you.
-
-To choose, which API elements your docgrok is able to handle, you have
-to define a handler class. This is what we want to do next.
-
-
-Create a handler and register your new docgrok
-++++++++++++++++++++++++++++++++++++++++++++++
-
-Those steps are described in the ftests for the docgrok module in
-grok.ftests.admin.docgrok. There you can also find examples, how to
-create own docgrok documentation (see the lower parts of the file).
-
-
-The Specialists
----------------
-
-``DocGrokPackage`` - The package doctor
-+++++++++++++++++++++++++++++++++++++++
-
-XXX: to be written.
-
-
-``DocGrokModule`` - The module doctor
-+++++++++++++++++++++++++++++++++++++
-
-XXX: to be written.
-
-
-``DocGrokClass`` - The class doctor
-+++++++++++++++++++++++++++++++++++
-
-XXX: to be written.

Deleted: grokui.admin/branches/introspectorless/src/grokui/admin/inspect.txt
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/inspect.txt	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/inspect.txt	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,101 +0,0 @@
-=======
-Inspect
-=======
-
-Grok's own object inspector.
-
-The Grok object browser is basically simply a view on objects.
-
-.. contents::
-
-
-How to use it
--------------
-
-You can use the object inspector through-the-web (TTW) or using
-Python. It was primarily designed for TTW-use. This is explained
-here.
-
-
-Simple usage: Inspecting easy reachable objects
------------------------------------------------
-
-The inspector is called by appending ``/@@inspect.html`` to an URL
-describing an object in the ZODB. For example, to watch the object
-description of your Zopes root folder, you can use something like:
-
-	    http://localhost:8080/@@inspect.html
-
-Note, that not all URLs you type into your browser denote
-objects. They often describe only certain views of certain
-objects. Currently the browsing of views with the object inspector is
-not supported.
-
-If you want to examine another object, which is reachable 'via URL',
-just get the path you would normally enter into the browser and append
-``@@inspect.html``.
-
-Assuming you once created an object, which is reachable by::
-
-	 http://localhost:8080/my_object
-
-then you can examine it via the object browser, using the following
-URL::
-
-         http://localhost:8080/my_object/@@inspect.html
-
-Easy, isn't it?
-
-In most cases you can also skip the 'eyes', the strange ``@@`` symbol
-in front of the view name (``inspect.html``). The 'eyes' are only
-neccessary, when you examine an object, which has got an own attribute
-called ``inspect.html``.
-
-
-Extended usage: Inspecting 'hidden' objects
--------------------------------------------
-
-All objects we exmined so far, are 'easy reachable'. This means, they
-are reachable by entering a simple URL. However, some (to tell the
-truth: many) objects cannot be reached this way. Such objects might be
-'subobjects' of others, they might be handled by a special traverser,
-simply have no view or whatever. We call those objects here 'hidden
-objects'. What, if we want to know more about
-those hidden objects?
-
-For example, we might have the attribute of an object (which is an
-object as well), which is not directly callable::
-
-  http://localhost:8080/my_object/hidden_attribute
-
-might so generate an error. It does not help to append simply
-``@@inspect.html`` to the URL. Instead we have to call a special
-traverser, which is able to look up the object for us and helps
-out. 
-
-This traverser is called by inserting ``docgrok-obj/`` as root of
-the path in the URL. The above mentioned hidden_attribute can
-therefore be reached using::
-
-  http://localhost:8080/docgrok_obj/my_object/hidden_attribute/@@inspect.html
-
-Such, you can reach even deeply nested subobjects of subobjects. 
-
-Just think of ``docgrok-obj`` as a special URL-namespace like
-``++annotations++``, ``++view++`` or similar (in fact it is not a
-URL-namespace), which can examine the complete object tree stored in
-the ZODB. In fact this 'namespace' can be used with every object, also
-with 'visible' ones. The above call to see ``my_object`` could
-therefore be reached (in a more complicated way) as::
-
-  http://localhost:8080/docgrok_obj/my_object/@@inspect.html
-
-This is the most general form to call the object browser:
-
-  http://<hostname>[:<port>]/docgrok_obj/<object-path>/@@inspect.html
-
-where 'docgrok-obj/' and '@@inspect.html' are the object browser
-specific parts.
-
-
-

Deleted: grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,569 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation 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.
-#
-##############################################################################
-"""Information about objects.
-
-This module provides wrappers/proies to give information about
-objects at runtime. See inspect.txt to learn more about retrieving
-object information using ObjectInfos.
-"""
-import inspect
-import re
-import types
-from types import MethodType
-
-import grok
-from grokui.admin.utilities import isContainingEvilRegExpChars
-
-import zope
-from zope.interface import Interface, implementedBy
-from zope.interface.common.sequence import IExtendedReadSequence
-from zope.interface.common.mapping import IEnumerableMapping
-from zope.annotation.interfaces import IAnnotatable, IAnnotations
-from zope.app.apidoc import utilities
-from zope.location import location
-from zope.schema import getFields
-from zope.security.checker import getCheckerForInstancesOf
-from zope.security.proxy import removeSecurityProxy
-from zope.traversing.api import getParent, getRoot
-from zope.traversing.interfaces import IPhysicallyLocatable
-from zope.dublincore.interfaces import IZopeDublinCore
-from zope.app.folder import rootFolder
-
-
-
-class ObjectInfo(grok.Model):
-    """An inspect proxy to provide object specific data.
-
-    This is a base proxy, which can handle all (and only)
-    Python-related data. See objectinfo.txt to learn more about
-    ObjectInfos.
-    """
-    obj = None
-
-    def __init__(self, obj):
-        self.obj = obj
-
-    def getmembers(self, predicate=None):
-        """Return all the members of an object in a list of (name,
-        value) pairs sorted by name.
-
-        If the optional predicate argument is supplied, only members
-        for which the predicate returns a true value are included.
-        """
-        return inspect.getmembers(self.obj, predicate)
-
-    def getmoduleinfo(self):
-        """Get information about modules.
-
-        Return a tuple of values that describe how Python will
-        interpret the file identified by path if it is a module, or
-        None if it would not be identified as a module. The return
-        tuple is (name, suffix, mode, mtype), where name is the name
-        of the module without the name of any enclosing package,
-        suffix is the trailing part of the file name (which may not be
-        a dot-delimited extension), mode is the open() mode that would
-        be used ('r' or 'rb'), and mtype is an integer giving the type
-        of the module. mtype will have a value which can be compared
-        to the constants defined in the imp module; see the
-        documentation for that module for more information on module
-        types.
-        """
-        path = getattr(self.obj, '__file__', None)
-        if path is None:
-            return
-        return inspect.getmoduleinfo(path)
-
-    def getmodulename(self):
-        """Return the name of the module named by the file path,
-        without including the names of enclosing packages. This uses
-        the same algorithm as the interpreter uses when searching for
-        modules. If the name cannot be matched according to the
-        interpreter's rules, None is returned.
-        """
-        path = getattr(self.obj, '__file__', None)
-        if path is None:
-            return
-        return inspect.getmodulename(path)
-
-    def ismodule(self):
-        """Return true if the object is a module.
-        """
-        return inspect.ismodule(self.obj)
-
-    def isclass(self):
-        """Return true if the object is a class.
-        """
-        return inspect.isclass(self.obj)
-
-    def ismethod(self):
-        """Return true if the object is a method.
-        """
-        return inspect.ismethod(self.obj)
-
-    def isfunction(self):
-        """Return true if the object is a Python function or unnamed
-        (lambda) function.
-        """
-        return inspect.isfunction(self.obj)
-
-    def istraceback(self):
-        """Return true if the object is a traceback.
-        """
-        return inspect.istraceback(self.obj)
-
-    def isframe(self):
-        """Return true if the object is a frame.
-        """
-        return inspect.isframe(self.obj)
-
-    def iscode(self):
-        """Return true if the object is a code.
-        """
-        return inspect.iscode(self.obj)
-
-    def isbuiltin(self):
-        """Return true if the object is a built-in function.
-        """
-        return inspect.isbuiltin(self.obj)
-
-    def isroutine(self):
-        """Return true if the object is a user-defined or built-in
-        function or method.
-        """
-        return inspect.isroutine(self.obj)
-
-    def ismethoddescriptor(self):
-        """Return true if the object is a method descriptor, but not
-        if ismethod() or isclass() or isfunction() are true.
-
-        This is new as of Python 2.2, and, for example, is true of
-        int.__add__. An object passing this test has a __get__
-        attribute but not a __set__ attribute, but beyond that the set
-        of attributes varies. __name__ is usually sensible, and
-        __doc__ often is.
-
-        Methods implemented via descriptors that also pass one of the
-        other tests return false from the ismethoddescriptor() test,
-        simply because the other tests promise more - you can, e.g.,
-        count on having the im_func attribute (etc) when an object
-        passes ismethod().
-        """
-        return inspect.ismethoddescriptor(self.obj)
-
-    def isdatadescriptor(self):
-        """Return true if the object is a data descriptor.
-
-        Data descriptors have both a __get__ and a __set__
-        attribute. Examples are properties (defined in Python),
-        getsets, and members. The latter two are defined in C and
-        there are more specific tests available for those types, which
-        is robust across Python implementations. Typically, data
-        descriptors will also have __name__ and __doc__ attributes
-        (properties, getsets, and members have both of these
-        attributes), but this is not guaranteed. New in version 2.3.
-        """
-        return inspect.isdatadescriptor(self.obj)
-
-    def isgetsetdescriptor(self):
-        """Return true if the object is a getset descriptor.
-
-        getsets are attributes defined in extension modules via
-        PyGetSetDef structures. For Python implementations without
-        such types, this method will always return False.
-
-        New in version 2.5.
-        """
-        return inspect.isgetsetdescriptor(self.obj)
-
-    def ismemberdescriptor(self):
-        """Return true if the object is a member descriptor.
-
-        Member descriptors are attributes defined in extension modules
-        via PyMemberDef structures. For Python implementations without
-        such types, this method will always return False.
-
-        New in version 2.5.
-        """
-        return inspect.ismemberdescriptor(self.obj)
-
-    #
-    # Source code related...
-    #
-    def getdoc(self):
-        """Get the documentation string for an object.
-
-        All tabs are expanded to spaces. To clean up docstrings that
-        are indented to line up with blocks of code, any whitespace
-        than can be uniformly removed from the second line onwards is
-        removed.
-        """
-        return inspect.getdoc(self.obj)
-
-    def getcomments(self):
-        """Get comments for an object.
-
-        Return in a single string any lines of comments immediately
-        preceding the object's source code (for a class, function, or
-        method), or at the top of the Python source file (if the
-        object is a module).
-
-        Due to a bug in ``inspect.getsource()`` no objects can be
-        handled, which contain a regular expression specific char in
-        their string representation.
-
-        """
-        if isContainingEvilRegExpChars(str(self.obj)):
-            return
-        return inspect.getcomments(self.obj)
-
-    def getfile(self):
-        """Return the name of the (text or binary) file in which an
-        object was defined.
-
-        If the object is a built-in module, class or function,
-        ``None`` will be returned.
-        """
-        try:
-            return inspect.getfile(self.obj)
-        except TypeError:
-            return
-
-    def getmodule(self):
-        """Try to guess which module an object was defined in.
-        """
-        return inspect.getmodule(self.obj)
-
-    def getsourcefile(self):
-        """Return the name of the Python source file in which an
-        object was defined.
-
-        If the object is a built-in module, class or function,
-        ``None`` will be returned.
-        """
-        try:
-            return inspect.getsourcefile(self.obj)
-        except TypeError:
-            return
-
-    def getsourcelines(self):
-        """Return a list of source lines and starting line number for
-        an object.
-
-        The argument may be a module, class, method, function,
-        traceback, frame, or code object. The source code is returned
-        as a list of the lines corresponding to the object and the
-        line number indicates where in the original source file the
-        first line of code was found. An IOError is raised if the
-        source code cannot be retrieved.
-        """
-        try:
-            return inspect.getsourcelines(self.obj)
-        except TypeError:
-            return
-        return 
-
-    def getsource(self):
-        """Return the text of the source code for an object.
-
-        The argument may be a module, class, method, function,
-        traceback, frame, or code object. The source code is returned
-        as a single string. An IOError is raised if the source code
-        cannot be retrieved.
-
-        Due to a bug in ``inspect.getsource()`` no objects can be
-        handled, which contain a regular expression specific char in
-        their string representation.
-        """
-        if isContainingEvilRegExpChars(str(self.obj)):
-            return
-
-        try:
-            return inspect.getsource(self.obj)
-        except TypeError:
-            return
-        return
-
-    def traverse(self, name):
-        new_obj = None
-
-        # Try to get name as dict entry...
-        keygetter = getattr(self.obj, 'keys', None)
-        if inspect.ismethod(keygetter):
-            if name in keygetter():
-                new_obj = self.obj[name]
-
-        # Try to get name as sequence entry...
-        if not new_obj:
-            # This is not the appropriate way to handle iterators. We
-            # must find somehing to handle them too.
-            try:
-                name_int = int(name)
-                if name_int in range(0, len(self.obj)):
-                    new_obj = self.obj[name_int]
-            except ValueError:
-                pass
-
-        # Get name as obj attribute...
-        if not new_obj and hasattr(self.obj, name):
-            new_obj = getattr(self.obj, name, None)
-
-        # Get name as annotation...
-        if not new_obj:
-            naked = zope.security.proxy.removeSecurityProxy(self.obj)
-            try:
-                annotations = IAnnotations(naked)
-                new_obj = name and name in annotations and annotations[name]
-                if not new_obj:
-                    new_obj = annotations
-            except TypeError:
-                pass
-
-        # Give obj a location...
-        if new_obj:
-            if not IPhysicallyLocatable(new_obj, False):
-                new_obj = location.LocationProxy(
-                    new_obj, self.obj, name)
-
-            new_info = ZopeObjectInfo(new_obj)
-            new_info.__parent__ = self
-            new_info.__name__ = name
-            return new_info
-
-        # name not found...
-        return
-
-
-
-
-
-class ZopeObjectInfo(ObjectInfo):
-    """Zope specific data.
-    """
-
-    def __init__(self, obj):
-        self.obj = obj
-        self.__klass = getattr(obj, '__class__', None) or type(obj)
-        self.__interfaces = tuple(implementedBy(self.__klass))
-
-    def getTypeLink(self, obj_type):
-        if obj_type is types.NoneType:
-            return
-        path = utilities.getPythonPath(obj_type)
-        return path.replace('.', '/')
-
-    def isLinkable(self, obj):
-        """We consider all but some basic types to be linkable for docgrok.
-
-        Although even simple strings can be displayed by a docgrok, it
-        does not make much sense. We therefore simply forbid such
-        links, filtering objects of basic types out.
-        """
-        for typespec in [types.NoneType, types.TypeType, types.BooleanType,
-                         types.IntType, types.LongType, types.FloatType,
-                         types.ComplexType, types.StringTypes,
-                         types.MethodType, types.BuiltinFunctionType,
-                         types.LambdaType, types.GeneratorType, types.CodeType,
-                         types.FileType, types.TracebackType, types.FrameType,
-                         types.BufferType, types.NotImplementedType]:
-            if isinstance(obj, typespec):
-                return False
-        return True
-
-    def getParent(self):
-        return getParent(self.obj)
-
-    def getPythonPath(self):
-        return utilities.getPythonPath(self.obj)
-
-    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)]
-
-    def getProvidedInterfaces(self):
-        return self.__interfaces
-
-    def getBases(self):
-        """Get base classes.
-        """
-        klass = getattr(self.obj, '__class__', None)
-        return getattr(klass, '__bases__', None)
-
-    def getAttributes(self):
-        """Get all attributes of an object.
-
-        See objectinfo.txt to learn more.
-        """
-        klass = removeSecurityProxy(self.__klass)
-        obj = removeSecurityProxy(self.obj)
-        for name in dir(obj):
-            value = getattr(obj, name, None)
-            if value is None:
-                continue
-            if inspect.ismethod(value) or inspect.ismethoddescriptor(value):
-                continue
-            entry = {
-                'name': name,
-                'value': `value`,
-                'value_linkable': self.isLinkable(value),
-                'type' : type(value),
-                # type_link is a very browser oriented data
-                # element. Move it to a view?
-                'type_link': self.getTypeLink(type(value)),
-                'interface': utilities.getInterfaceForAttribute(
-                                 name, klass=klass)
-                }
-            entry.update(utilities.getPermissionIds(
-                name, getCheckerForInstancesOf(klass)))
-            yield entry
-
-    def getMethods(self):
-        """Get all methods of an object.
-
-        Get a list of dicts, describing the methods of an object. The
-        dicts support keys ``name`` (name of method), ``signature``,
-        ``doc`` (method's docstring or ``None``) and ``interface``
-        (the interface, where the method was defined or ``None``).
-        """
-        klass = removeSecurityProxy(self.__klass)
-        obj = removeSecurityProxy(self.obj)
-        for name in dir(obj):
-            value = getattr(obj, name, None)
-            if value is None:
-                continue
-            if not (inspect.ismethod(value)
-                    and not inspect.ismethoddescriptor(value)):
-                continue
-            if inspect.ismethod(value):
-                signature = utilities.getFunctionSignature(value)
-            else:
-                signature = '(...)'
-
-            entry = {
-                'name': name,
-                'signature' : signature,
-                'doc' : getattr(value, '__doc__', None),
-                'interface': utilities.getInterfaceForAttribute(
-                                 name, klass=klass),
-                'value_linkable': self.isLinkable(value),
-                }                
-            entry.update(utilities.getPermissionIds(
-                name, getCheckerForInstancesOf(klass)))
-            yield entry
-        
-    def isSequence(self):
-        """Is the object observed a sequence?
-        """
-        if isinstance(self.obj, types.ListType):
-            return True
-        if isinstance(self.obj, types.TupleType):
-            return True
-        return IExtendedReadSequence.providedBy(self.obj)
-
-    def getSequenceItems(self):
-        """Get the items of a sequence.
-
-        Returns a list of dicts, each representing one element of the
-        sequence.
-        """
-        if not self.isSequence():
-            return
-        
-        elems = []
-        naked = removeSecurityProxy(self.obj)
-        for index in xrange(0, len(self.obj)):
-            value = naked[index]
-            elems.append({
-                'index' : index,
-                'value' : value,
-                'value_type' : type(value),
-                'value_type_link' : self.getTypeLink(type(value)),
-                'value_linkable': self.isLinkable(value),
-                })
-        return elems
-
-    def isMapping(self):
-        """Is the object observed a mapping?
-
-        Mappings are those objects, which are dicts or provide
-        IEnumerableMapping.
-        """
-        if isinstance(self.obj, types.DictType):
-            return True
-        return IEnumerableMapping.providedBy(self.obj)
-
-    def getMappingItems(self):
-        """Get the elements of a mapping.
-
-        The elements are delivered as a list of dicts, each dict
-        containing the keys ``key``, ``key_string`` (the key as a
-        string), ``value``, ``value_type`` and ``value_type_link``.
-        """
-        elems = []
-        naked = removeSecurityProxy(self.obj)
-        if not hasattr(naked, 'items'):
-            return []
-        for key, value in naked.items():
-            elems.append({
-                'key' : key,
-                'key_string' : `key`,
-                'value' : value,
-                'value_type' : type(value),
-                'value_type_link' : self.getTypeLink(type(value)),
-                'value_linkable': self.isLinkable(value),
-                })
-        return elems
-
-    def isAnnotatable(self):
-        """Does the object observed expect to be annotated?
-        """
-        return IAnnotatable.providedBy(self.obj)
-
-
-    def getAnnotationsInfo(self):
-        """Get all annotations associated with an object.
-
-        If no annotations are associated with the object, ``None`` is
-        returned. Otherwise we get a list of dicts, each containing
-        keys ``key``, ``key_string`` (textual representation of key),
-        ``value``, ``value_type`` and ``value_type_link''.
-        """
-        if not self.isAnnotatable():
-            return []
-        naked = removeSecurityProxy(self.obj)
-        annotations = IAnnotations(naked)
-        if not hasattr(annotations, 'items'):
-            return []
-        elems = []
-        for key, value in annotations.items():
-            elems.append({
-                'key' : key,
-                'key_string' : `key`,
-                'value' : value,
-                'value_type' : type(value),
-                'value_type_link' : self.getTypeLink(type(value)),
-                'value_linkable': self.isLinkable(value),
-                'obj' : annotations[key]
-                })
-        return elems
-
-    def getId(self):
-        """Try to determine some kind of name.
-        """
-        return (getattr(self.obj, '__name__', None)
-               or getattr(self.obj, 'id', None)
-               or getattr(self.obj, '_o_id', None))
-

Deleted: grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.txt
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.txt	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/objectinfo.txt	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,651 +0,0 @@
-============
-Object Infos
-============
-
-Retrieve information about objects. 
-
-ObjectInfos are used by the Grok object browser to retrieve the data
-displayed in the ``inspect.html`` view. See inspect.txt to learn more
-about using the inspector.
-
-.. contents::
-
-
-ObjectInfo:
------------
-
-Object infos are in fact wrappers for the functionality offered by the
-Python standard library ``inspect``.
-
-Let's create a simple class:
-
-  >>> class Mammoth(object):
-  ...    """A mammoth."""
-  ...    pass
-
-Now create an object. Meet Manfred:
-
-  >>> manfred = Mammoth()
-  >>> manfred
-  <Mammoth object at ...>
-
-An ObjectInfo's job is it, to find out as much as possible about
-Manfred. We create an ObjectInfo by giving the object to examine as
-parameter: 
-
-  >>> from grokui.admin.objectinfo import ObjectInfo
-  >>> info = ObjectInfo(manfred)
-  >>> info
-  <grokui.admin.objectinfo.ObjectInfo object at ...>
-
-What can we know about Manfred now?
-
-  >>> members = info.getmembers()
-  >>> ('__class__', Mammoth) in members
-  True
-
-  >>> info.getmoduleinfo() is None
-  True
-
-A Mammoth is not a module. Let's see, what happens when we examine a
-real module:
-
-  >>> import grokui.admin.objectinfo
-  >>> ObjectInfo(grokui.admin).getmoduleinfo() in [('__init__', '.pyc',
-  ... 'rb', 2), ('__init__', '.py', 'U', 1)]
-  True
-
-  >>> info.getmodulename() is None
-  True
-
-  >>> ObjectInfo(grokui.admin.objectinfo).getmodulename()
-  'objectinfo'
-
-  >>> info.isclass()
-  False
-
-manfred is not a class, but an instance of a class. This information
-is correct.
-
-  >>> ObjectInfo(Mammoth).isclass()
-  True
-
-  >>> info.ismethod()
-  False
-
-  >>> ObjectInfo(info.ismethod).ismethod()
-  True
-
-  >>> info.isfunction()
-  False
-
-  >>> def f():
-  ...    pass
-
-  >>> ObjectInfo(f).isfunction()
-  True
-
-  >>> info.istraceback()
-  False
-
-  >>> info.isframe()
-  False
-
-  >>> info.iscode()
-  False
-
-  >>> info.isbuiltin()
-  False
-
-  >>> ObjectInfo(dir).isbuiltin()
-  True
-
-  >>> info.isroutine()
-  False
-
-  >>> info.ismethoddescriptor()
-  False
-
-  >>> info.isdatadescriptor()
-  False
-
-  >>> info.getdoc()
-  'A mammoth.'
-
-  >>> info.getcomments() is None
-  True
-
-We have a comment in the sources of ObjectInfo:
-
-  >>> ObjectInfo(grokui.admin.objectinfo.ObjectInfo.getdoc).getcomments()
-  '# Source code related...\n'
-
-A bug in ``inspect.getcomments()`` causes objects with regular
-expression chars ('+', '*', etc.) in their name to fail. A workaround
-should check this and give ``None`` instead:
-
-  >>> evil_obj = Mammoth()
-  >>> evil_obj.__str__ = '+++evil+++'
-  >>> ObjectInfo(evil_obj).getcomments() is None
-  True
-
-``getfile()`` gives the name of the file the object was defined
-in. Contrary to the inspect method, this one returns None, if the
-object is a built-in module, class or function.
-
-  >>> info.getfile() is None
-  True
-
-The filename can be a compiled file ('.pyc') or a Python source file
-('.py'):
-
-  >>> filename = ObjectInfo(grokui.admin.objectinfo.ObjectInfo).getfile()
-  >>> filename = filename[-1] == 'c' and filename or filename + 'c'
-  >>> pnorm(filename)
-  '.../grokui/admin/objectinfo.pyc'
-
-
-  >>> info.getmodule()
-  <module '__builtin__' (built-in)>
-
-
-Here the same applies as for getfile().
-
-  >>> info.getsourcefile() is None
-  True
-
-  >>> pnorm(ObjectInfo(grokui.admin.objectinfo.ObjectInfo).getsourcefile())
-  '.../grokui/admin/objectinfo.py'
-
-  >>> info.getsourcelines() is None
-  True
-
-  >>> ObjectInfo(grokui.admin.objectinfo.ObjectInfo.isclass).getsourcelines()
-  (['    def isclass(self):\n',...)
-
-  >>> ObjectInfo(len).getsourcefile() is None
-  True
-
-  >>> info.getsource() is None
-  True
-
-  >>> ObjectInfo(grokui.admin.objectinfo.ObjectInfo.isclass).getsource()
-  '    def isclass(self):\n...'
-
-A bug in ``inspect.getsource()`` causes objects with regular
-expression chars ('+', '*', etc.) in their name to fail. This is true
-for objects like '+++etc++site' and friends. A workaround should check
-this and give ``None`` instead:
-
-  >>> evil_obj = Mammoth()
-  >>> evil_obj.__str__ = '+++evil+++'
-  >>> ObjectInfo(evil_obj).getsource() is None
-  True
-
-
-ZopeObjectInfo
---------------
-
-All information, which is special for Zope objects, can be digged
-using ``ZopeObjectInfo``. Zope specific are especially things related
-to the ZODB or interfaces.
-
-
-Preliminaries
-+++++++++++++
-
-We first setup some objects, that we can examine thereafter. Let's
-create a ZopeObjectInfo for a typical Zope object, the root
-folder. First get the root folder:
-
-  >>> from zope.app.folder import rootFolder
-  >>> root = rootFolder()
-  >>> root
-  <zope.app.folder.folder.Folder object at ...>
-
-Then get an associated ZopeObjectInfo:
-
-  >>> from grokui.admin.objectinfo import ZopeObjectInfo
-  >>> root_info = ZopeObjectInfo(root)
-  >>> root_info
-  <grokui.admin.objectinfo.ZopeObjectInfo object at ...>
-
-We create a folder in the root:
-
-  >>> from zope.app.folder.folder import Folder
-  >>> subfolder = Folder()
-  >>> root['Savannah'] = subfolder
-
-and get a ZopeObjectInfo for it as well:
-
-  >>> subfolder_info = ZopeObjectInfo(subfolder)
-  >>> subfolder_info
-  <grokui.admin.objectinfo.ZopeObjectInfo object at ...>
-
-Finally, we create some content in the subfolder. A cave, where
-Manfred can stay
-
-  >>> import grok
-  >>> class Cave(grok.Container):
-  ...    """A home, sweet home."""
-  ...    pass
-
-  >>> sweethome = Cave()
-  >>> subfolder['SweetHome'] = sweethome
-  >>> sweethome_info = ZopeObjectInfo(sweethome)
-  >>> sweethome_info
-  <grokui.admin.objectinfo.ZopeObjectInfo object at ...>
-
-and put Manfred into the cave:
-
-  >>> sweethome['Owner'] = manfred
-  >>> manfred_info = ZopeObjectInfo(manfred)
-  >>> manfred_info
-   <grokui.admin.objectinfo.ZopeObjectInfo object at ...>
-
-Now we can examine the objects further.
-
-getId()
-+++++++
-
-Objects' names can be stored in a variety of attributes. It is
-therefore a bit difficult to get the right name (if any). ``getId``
-looks currently for ``__name__``, ``id`` and ``_o_id``. If all fails,
-``None`` is returned.
-
-  >>> root_info.getId() is None
-  True
-
-  >>> subfolder_info.getId()
-  u'Savannah'
-
-  >>> manfred_info.getId() is None
-  True
-
-getParent()
-+++++++++++
-
-What is the parent object of the
-root?
-
-  >>> root_info.getParent() is None
-  True
-
-  >>> subfolder_info.getParent()
-  <zope.app.folder.folder.Folder object at ...>
-
-Oh, a folder. Is it the root?
-
-  >>> subfolder_info.getParent() == root
-  True
-
-What about the sweet home?
-
-  >>> sweethome_info.getParent()
-  <zope.app.folder.folder.Folder object at ...>
-
-  >>> sweethome_info.getParent() == subfolder
-  True
-
-Last not least, Manfred:
-
-  >>> manfred_info.getParent()
-  Traceback (most recent call last):
-  ...
-  TypeError: ('Not enough context information to get parent', <Mammoth object at ...>)
-
-Oops! Well, mammoths are not too smart. They wander around all the
-time and so sometimes they forget where they are. Technically,
-Mammoths are not locatable in sense of ILocatable. We can make them
-locatable setting two attributes:
-
-  >>> manfred.__parent__ = sweethome
-  >>> manfred.__name__ = u'Manfred'
-
-Afterwards we can tell, where Manfred lives:
-
-  >>> manfred_info.getParent()
-  <Cave object at ...>
-
-
-getDirectlyProvidedInterfaces()
-+++++++++++++++++++++++++++++++
-
-Gives a list of interfaces provided *directly* by the objects in
-dotted-path notation.
-
-  >>> root_info.getDirectlyProvidedInterfaces()
-  ['zope.app.folder.interfaces.IRootFolder']
-
-  >>> subfolder_info.getDirectlyProvidedInterfaces()
-  []
-
-  >>> sweethome_info.getDirectlyProvidedInterfaces()
-  []
-
-  >>> manfred_info.getDirectlyProvidedInterfaces()
-  []
-
-
-getInterfaces()
-+++++++++++++++
-
-Gives a tuple of all interfaces provided by the object, not only the
-directly provided ones.
-
-  >>> root_info.getProvidedInterfaces()
-  (<InterfaceClass zope.app.folder.interfaces.IFolder>, <InterfaceClass persistent.interfaces.IPersistent>, <InterfaceClass zope.location.interfaces.IPossibleSite>, <InterfaceClass zope.app.container.interfaces.IContained>)
-
-  >>> sweethome_info.getProvidedInterfaces()
-  (<InterfaceClass zope.annotation.interfaces.IAttributeAnnotatable>, <InterfaceClass grok.interfaces.IContainer>, ...<InterfaceClass zope.app.container.interfaces.IContained>, <InterfaceClass persistent.interfaces.IPersistent>)
-
-Manfred again, is a bit too plain to give us interesting information:
-
-  >>> manfred_info.getProvidedInterfaces()
-  ()
-
-
-getBases()
-++++++++++
-
-What bases built our objects?
-
-  >>> root_info.getBases()
-  (<type 'persistent.Persistent'>, <class 'zope.app.component.site.SiteManagerContainer'>, <class 'zope.app.container.contained.Contained'>)
-
-  >>> sweethome_info.getBases()
-  (<class 'grok.components.Container'>,)
-
-  >>> manfred_info.getBases()
-  (<type 'object'>,)
-
-
-getAttributes()
-+++++++++++++++
-
-Attributes are members, which are not methods nor methoddescriptors
-(according to ``inspect`` package). This method gives (contrary to the
-apidoc method with same name) *all* attributes, also the 'private'
-ones, because some private attributes can be of interest, when
-debugging happens.
-
-Attributes are given as an iterator over dicts, each dict containing
-the keys 
-
-- ``name``: name of attribute.
-
-- ``value``: value of attribute as string.
-
-- ``value_linkable``: 
-
-  a boolean indicating, whether the attribute is reachable directly,
-  for instance calling a special URL. Linkable values can be examined
-  further by calling the current URL and inserting the name of
-  attribute. Example: an object examined by
-
-	     http://localhost:8080/someobj/inspect.html
-
-  which owns a linkable attribute ``myattr`` can be examined by
-
-             http://localhost:8080/someobj/myattr/inspect.html
-
-- ``type``: type of value as string.
-
-- ``type_link``: link to the type documentation as str.
-
-- ``interface``: name of the interface, this attribute was defined in
-  or ``None``.
-
-- ``read_perm`` and ``write_perm``: permissions to read/write the
-  attribute. 
-
-To get the attributes as a list, you can use ``list()`` as shown
-below.
-
-We now look for the attributes of the root folder:
-
-  >>> attrs = list(root_info.getAttributes())
-
-There should be a ``data`` attribute available:
-
-  >>> attr_names = [x['name'] for x in attrs]
-  >>> 'data' in attr_names
-  True
-
-And the ``data`` attribute should have eight entries (as described
-above): 
-
-  >>> data_attr = [x for x in attrs if x['name'] == 'data'][0]
-  >>> len(data_attr)
-  8
-
-First, let's determine the name of the attribute:
-
-  >>> data_attr['name']
-  'data'
-
-The value of the attribute:
-
-  >>> data_attr['value']
-  '<BTrees.OOBTree.OOBTree object at ...>'
-
-The value is directly reachable using the traverser:
-
-  >>> data_attr['value_linkable']
-  True
-
-We can get some information about the type of the value:
-
-  >>> data_attr['type']
-  <type 'BTrees.OOBTree.OOBTree'>
-
-  >>> data_attr['type_link']
-  'BTrees/OOBTree/OOBTree'
-
-Is there an interface this attribute was defined in?
-
-  >>> data_attr['interface'] is None
-  True
-
-There are no special permissions defined to read or write the 'data'
-attribute. 
-
-  >>> data_attr['read_perm'] is None
-  True
-
-  >>> data_attr['write_perm'] is None
-  True
-
-
-getMethods()
-++++++++++++
-
-This method gives (contrary to the apidoc method with same name) *all*
-methods, also the 'private' ones, because some private attributes can
-be of interest, when debugging happens.
-
-Methods are given as an iterator over dicts, each dict containing
-the keys 
-
-- ``name``: the name of the method.
-
-- ``signature``: the signature of the methods as string.
-
-- ``doc``: an doc string of the method (if one exists)
-
-- ``interface``: the interface this method was implemented at (if
-  any).
-
-- ``read_perm`` and ``write_perm``: permissions to read/write the
-  method. 
-
-We first get the methods of the root object. Because ``getMethods``
-returns an iterable, we form a list, using ``list()``:
-
-  >>> methods = list(root_info.getMethods())
-
-  >>> len(methods)
-  13
-
-Okay, there are 13 methods defined in this object. We pick one to
-examine it further:
-
-  >>> items_method = [x for x in methods if x['name'] == 'items'][0]
-  >>> len(items_method)
-  7
-
-There are six keys in the dict describing the ``items()`` method of
-the root folder.
-
-  >>> items_method['name']
-  'items'
-
-The ``items()`` method takes no parameters:
-
-  >>> items_method['signature']
-  '()'
-
-The method is documented:
-
-  >>> items_method['doc']
-  'Return a sequence-like object containing tuples of the form\n           (name, object) for the objects that appear in the folder.\n        '
-
-This is the raw documentation string, obviously. It can be formatted
-using render methods defined in the inspect view class.
-
-The method has no special interface where it was defined:
-
-  >>> items_method['interface'] is None
-  True
-
-And there are no special permissions set on this method:
-
-  >>> items_method['read_perm'] is None
-  True
-
-  >>> items_method['write_perm'] is None
-  True
-
-
-isSequence()
-++++++++++++
-
-Sequences are those objects, which provide the IExtendedReadSequence
-interface, are of tuple type or of list type.
-
-  >>> root_info.isSequence()
-  False
-
-  >>> ZopeObjectInfo(['a', 'list', 'of', 'values']).isSequence()
-  True
-
-  >>> ZopeObjectInfo(('a', 'tuple', 'of', 'values')).isSequence()
-  True
-
-  >>> ZopeObjectInfo({'a': 'dict', 'of': 'values'}).isSequence()
-  False
-
-
-getSequenceItems()
-++++++++++++++++++
-
-  >>> testlist = ['a', 'list', 'of', 'values']
-  >>> list_info = ZopeObjectInfo(testlist).getSequenceItems()
-  >>> len(list_info)
-  4
-
-  >>> first_elem = list_info[0]
-  >>> first_elem['index']
-  0
-
-  >>> first_elem['value_type']
-  <type 'str'>
-
-  >>> first_elem['value_type_link']
-  '__builtin__/str'
-
-  >>> first_elem['value']
-  'a'
-
-
-isMapping()
-+++++++++++
-
-  >>> root_info.isMapping()
-  True
-
-  >>> ZopeObjectInfo(['a', 'list', 'of', 'values']).isMapping()
-  False
-
-  >>> ZopeObjectInfo(('a', 'tuple', 'of', 'values')).isMapping()
-  False
-
-  >>> ZopeObjectInfo({'a': 'dict', 'of': 'values'}).isMapping()
-  True
-
-  >>> ZopeObjectInfo(root.data).isMapping()
-  False
-
-
-getMappingItems()
-+++++++++++++++++
-
-  >>> map_elems = root_info.getMappingItems()
-  >>> u'Savannah' in [x['key'] for x in map_elems]
-  True
-
-  >>> map_elem = [x for x in map_elems if x['key'] == u'Savannah'][0]
-  >>> map_elem['key']
-  u'Savannah'
-
-  >>> map_elem['key_string']
-  "u'Savannah'"
-
-  >>> map_elem['value']
-  <zope.app.folder.folder.Folder object at ...>
-
-  >>> map_elem['value_type']
-  <class 'zope.app.folder.folder.Folder'>
-
-  >>> map_elem['value_type_link']
-  'zope/app/folder/folder/Folder'
-
-Objects, which are not mappings, should return the empty list:
-
-  >>> ZopeObjectInfo('a string').getMappingItems()
-  []
-
-isAnnotatable()
-+++++++++++++++
-
-Checks for the interface IAnnotatable. Most 'usual' Zope objects are
-annotatable...
-
-  >>> root_info.isAnnotatable()
-  True
-
-  >>> sweethome_info.isAnnotatable()
-  True
-
-...but some very simple ones are not (or have not declared to be
-annotatable although they are):
-
-  >>> manfred_info.isAnnotatable()
-  False
-
-
-getAnnotationsInfo()
-++++++++++++++++++++
-
-  >>> root_info.getAnnotationsInfo()
-  []
-
-  >>> sweethome_info.getAnnotationsInfo()
-  []
-
-Manfred is not annotatable, but instead of an error we get an empty
-list:
-
-  >>> manfred_info.getAnnotationsInfo()
-  []
-

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/security.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/security.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/security.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,16 +1,3 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation 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.
-#
-##############################################################################
 """Security notifications for `grokui.admin`.
 
 The machinery to do home-calling security notifications.

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/static/grok.css
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/static/grok.css	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/static/grok.css	2009-09-14 22:26:34 UTC (rev 103985)
@@ -200,6 +200,10 @@
 padding:0.5em;
 }
 
+.menu-box3 {
+  margin: 1em 0.5em;
+}
+
 .menu-description1 {
 margin-left:1.5em;
 }
@@ -208,60 +212,11 @@
 width: 40em;
 }
 
-/* ---- docgrok related ---- */
-.docgrok-entry {
-margin-bottom:0.5em;
+.menu-head1 h3 {
+  margin: 0.2em 0.3em;
 }
 
-.docgrok-value { 
-margin-left:2em;
-}
 
-.docgrok-pathvalue {
-font-family:courier;
-}
-
-.docgrok-annotation1 {
-margin-left:2em;
-}
-
-.docgrok-annotation2 {
-margin-left:5em;
-}
-
-.docgrok-pycode1 {
-color:#00f;
-font-family:courier;
-}
-
-.docgrok-sourcetext {
-background-color:#f8f8f8;
-border:2px groove #eee;
-margin:1em;
-padding:1.5em;
-}
-
-.docgrok-sourceheader {
-background-color:#fff;
-}
-
-.docgrok-table { 
-font-size:1.0em;
-empty-cells:show;
-border-collapse:separate;
-}
-.docgrok-table th { 
-padding-left:3px;
-padding-right:3px;
-border:1px solid #eee;
-}
-.docgrok-table td {
-min-height:1.0em;
-padding-left:5px;
-padding-right:5px;
-
-}
-
 /* --- system proces related --- */
 div#server-processes {
 background-color:#f9f9D4;

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/utilities.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/utilities.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/utilities.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -1,18 +1,3 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation 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.
-#
-##############################################################################
-"""Helper functions for grok admin.
-"""
 import httplib
 import pkg_resources
 import re
@@ -22,240 +7,7 @@
 from zope.tal.taldefs import attrEscape
 from urlparse import urlparse, urlunparse
 
-def getPathLinksForObject(obj, root_url=''):
-    """Given an object, this function returns HTML code with links to
-    documentation.
 
-    The object must provide a string representation like 'foo.blah
-    object at 0x9999999'. Returned is then a string, where 'foo' and
-    'blah' are embedded in HTML links to docgrok documentation for foo
-    and foo.blah.
-
-    The (optional) ``root_url`` is used to create the links to docgrok
-    documentation. It is expected to be the URL, which can generate
-    docgrok documentation by appending '/docgrok' to the URL.
-
-    We can use ObjectInfo objects to check this:
-
-      >>> from grokui.admin.objectinfo import ObjectInfo
-      >>> obj = ObjectInfo(None)
-      >>> obj
-      <grokui.admin.objectinfo.ObjectInfo object at ...>
-
-    Obviously we have a string representation of the required form
-    here. So we can get HTML with links to the documentation for
-    ``grok``, ``grokui.admin`` and so on.
-    
-      >>> from grokui.admin.utilities import getPathLinksForObject
-      >>> link = getPathLinksForObject(obj)
-      >>> link
-      "&lt;<a href='/docgrok/grokui/'>grokui</a>... object at ..."
-
-    We got a link to the ``grok`` documentation. Also a link to
-    ``grokui.admin`` is provided::
-
-      >>> link
-      "&lt;...<a href='/docgrok/grokui/admin/'>admin</a>... object at ..."
-
-    If we provide a root_url, we will find it in the links:
-
-      >>> link = getPathLinksForObject(obj, 'http://localhost:8080')
-      >>> link
-      "&lt;<a href='http://localhost:8080/docgrok/grokui...'>admin</a>..."
-
-    If no dotted path is included in objects strings representation, a
-    simple string without links is returned:
-    
-      >>> getPathLinksForObject(None)
-      "'None'"
-
-    HTML entities should be encoded. We set up a site-manager to get
-    an 'illegal' object representation including regular expression
-    chars ('+') and no dotted path:
-
-      >>> from zope.app.folder import rootFolder
-      >>> root = rootFolder()
-      >>> from zope.app.component import site
-      >>> sm = site.LocalSiteManager(root)
-      >>> root.setSiteManager(sm)
-      >>> sm
-      <LocalSiteManager ++etc++site>
-
-    This is a strange object identifier. Anyway:
-
-      >>> getPathLinksForObject(sm)
-      "'&lt;LocalSiteManager ++etc++site&gt;'"
-      
-    """
-    r_exp = re.compile("'<(.+)( object at .*)>'")
-    
-    raw = `str(obj)`
-    match = r_exp.match(raw)
-    if match is None:
-        return attrEscape(raw)
-
-    result = "&lt;"
-    url = root_url + '/docgrok/'
-    for part in match.group(1).split('.'):
-        url = url + part + '/'
-        result += "<a href='%s'>%s</a>." % (url, part)
-    if len(result) and result[-1] == '.':
-        result = "%s%s&gt;" % (result[:-1], match.group(2))
-        return result
-    return raw
-
-def getPathLinksForClass(klass, root_url=''):
-    """Given a class or classlike object, this function returns HTML
-    code with links to documentation.
-
-    The klass object must provide a string representation like '<class
-    foo.Bar>'. Returned is then a string, where 'foo' and
-    'Bar' are embedded in HTML links to docgrok documentation for foo
-    and foo.Bar.
-
-    The (optional) ``root_url`` is used to create the links to docgrok
-    documentation. It is expected to be the URL, which can generate
-    docgrok documentation by appending '/docgrok' to the URL.
-
-    We can use class ObjectInfo to check this:
-
-      >>> from grokui.admin.objectinfo import ObjectInfo
-      >>> ObjectInfo
-      <class 'grokui.admin.objectinfo.ObjectInfo'>
-
-      >>> from grokui.admin.utilities import getPathLinksForClass
-      >>> htmlcode = getPathLinksForClass(ObjectInfo)
-      >>> htmlcode
-      "&lt;class '<a href='/docgrok/grokui/'>grokui</a>...'&gt;"
-
-    When we provide a root_url the link will include it in the
-    href-attribute:
-
-      >>> getPathLinksForClass(ObjectInfo, 'http://localhost')
-      "&lt;class '<a href='http://localhost/docgrok/grokui/'>grokui</a>...'&gt;"
-
-    If the class does not provide an appropriate string
-    representation, we will get the representation without any links:
-
-      >>> getPathLinksForClass(None, 'http://localhost')
-      "'None'"
-
-    This also works with 'class-like' objects, for instance interfaces
-    and their interface-classes:
-
-      >>> from zope.app.folder import rootFolder
-      >>> from zope.interface import providedBy
-      >>> root = rootFolder()
-      >>> iface = list(providedBy(root))[0]
-      >>> iface
-      <InterfaceClass zope.app.folder.interfaces.IRootFolder>
-
-      >>> getPathLinksForClass(iface)
-      "&lt;InterfaceClass '<a href='/docgrok/zope/'>zope</a>...'&gt;"
-
-    HTML entities should be encoded. We set up a site-manager to get
-    an 'illegal' object representation including regular expression
-    chars ('+') and no dotted path:
-
-      >>> from zope.app.folder import rootFolder
-      >>> root = rootFolder()
-      >>> from zope.app.component import site
-      >>> sm = site.LocalSiteManager(root)
-      >>> root.setSiteManager(sm)
-      >>> sm
-      <LocalSiteManager ++etc++site>
-
-    This is a strange object identifier. Anyway:
-
-      >>> getPathLinksForClass(sm)
-      "&lt;LocalSiteManager '<a href='/docgrok/++etc++site/'>...</a>'&gt;"
-
-    """
-    r_exp = re.compile(".*<(.*) '?(.+)'?(.*)>.*")
-    raw = `str(klass)`
-    match = r_exp.match(raw)
-    if match is None:
-        return attrEscape(raw)
-
-    result = "&lt;%s '" % (match.group(1),)
-    url = root_url + '/docgrok/'
-    for part in match.group(2).split('.'):
-        url = "%s%s/" % (url, part)
-        result += "<a href='%s'>%s</a>." % (url, part)
-    if len(result) and result[-1] == '.':
-        result = "%s'%s&gt;" % (result[:-1], match.group(3))
-        return result
-    return raw
-
-def getPathLinksForDottedName(name, root_url=''):
-    """
-    """
-    if name is None:
-        return ''
-    result = ''
-    url = root_url + '/docgrok/'
-    for part in name.split('.'):
-        url = "%s%s/" % (url, part)
-        result += "<a href='%s'>%s</a>." % (url, part)
-    if len(result) and result.endswith('.'):
-        result = result[:-1]
-        return result
-    return name
-
-def isContainingEvilRegExpChars(strval):
-    """Check whether a string contains evil chars.
-
-    'Evil' with respect to regular expressions is a string, that
-    contains chars, with a special meaning in regular expressions.
-
-    We indeed must provide a string:
-
-       >>> from grokui.admin.utilities import isContainingEvilRegExpChars
-       >>> isContainingEvilRegExpChars(None)
-       Traceback (most recent call last):
-       ...
-       TypeError: expected string or buffer
-
-       >>> isContainingEvilRegExpChars('foo')
-       False
-
-       >>> isContainingEvilRegExpChars('foo++etc++bar')
-       True
-
-       >>> isContainingEvilRegExpChars('foo*bar')
-       True
-
-    """
-    evil_chars = re.compile('.*(\*|\+|\(|\)|\{|\}).*')
-    if evil_chars.match(strval):
-        return True
-    return False
-
-
-def getParentURL(url):
-    """Compute the parent URL for an object described by URL.
-
-       >>> from grokui.admin.utilities import getParentURL
-       >>> getParentURL('http://foo:8080/myobj')
-       'http://foo:8080/'
-
-       >>> getParentURL('http://foo:8080/myfoo/mybar')
-       'http://foo:8080/myfoo/'
-
-    We want an URL always to end with a slash:
-
-       >>> getParentURL('http://foo:8080')
-       'http://foo:8080/'
-
-    """
-    url_list = list(urlparse(url))
-    path = url_list[2]
-    if path.endswith('/'):
-        path = path[:-1]
-    path = path.rsplit('/', 1)[0] + '/'
-    url_list[2] = path
-    return urlunparse(url_list)
-
 def getURLWithParams(url, data=None):
     """Get the url with data appended as URL parameters.
 
@@ -272,6 +24,7 @@
         url += '?' + urllib.urlencode(data, doseq=True)
     return url
 
+
 def getVersion(pkgname):
     """Determine the version of `pkgname` used in background.
     """
@@ -280,6 +33,7 @@
         return info.version
     return None
 
+
 class TimeoutableHTTPConnection(httplib.HTTPConnection):
     """A customised HTTPConnection allowing a per-connection
     timeout, specified at construction.
@@ -312,6 +66,7 @@
         if not self.sock:
             raise socket.error, msg
 
+
 class TimeoutableHTTPHandler(urllib2.HTTPHandler):
     """A customised HTTPHandler which times out connection
     after the duration specified at construction.

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/view.py
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/view.py	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/view.py	2009-09-14 22:26:34 UTC (rev 103985)
@@ -21,16 +21,8 @@
 
 from grokui.admin.interfaces import ISecurityNotifier
 
-from grokui.admin import docgrok
-from grokui.admin.docgrok import DocGrok, DocGrokPackage, DocGrokModule
-from grokui.admin.docgrok import DocGrokTextFile, DocGrokGrokApplication
-from grokui.admin.docgrok import DocGrokClass, DocGrokInterface, getItemLink
-
-from grokui.admin.objectinfo import ZopeObjectInfo
 from grokui.admin.security import SecurityNotifier
-from grokui.admin.utilities import getPathLinksForObject, getPathLinksForClass
-from grokui.admin.utilities import getPathLinksForDottedName, getParentURL
-from grokui.admin.utilities import getURLWithParams, getVersion
+from grokui.admin.utilities import getVersion, getURLWithParams
 
 from ZODB.broken import Broken
 from ZODB.interfaces import IDatabase
@@ -44,13 +36,6 @@
 from zope.app.applicationcontrol.runtimeinfo import RuntimeInfo
 from zope.app.applicationcontrol.browser.runtimeinfo import RuntimeInfoView
 from zope.app.applicationcontrol.browser.zodbcontrol import ZODBControlView
-from zope.app.apidoc import utilities, codemodule
-from zope.app.apidoc.utilities import getPythonPath, renderText, columnize
-from zope.app.apidoc.codemodule.module import Module
-from zope.app.apidoc.codemodule.class_ import Class
-from zope.app.apidoc.codemodule.function import Function
-from zope.app.apidoc.codemodule.text import TextFile
-from zope.app.apidoc.codemodule.zcml import ZCMLFile
 from zope.app.folder.interfaces import IRootFolder
 from zope.app.security.interfaces import ILogout, IAuthentication
 from zope.app.security.interfaces import IUnauthenticatedPrincipal
@@ -73,9 +58,12 @@
     src = zope.component.getUtility(z3c.flashmessage.interfaces.IMessageSource, name='session')
     src.send(message, type)
 
+
+
 class ManageApplications(grok.Permission):
     grok.name('grok.ManageApplications')
 
+
 class GrokAdminInfoView(GrokCoreViewOrCodeView):
     """A base to provide machinereadable views.
     """
@@ -85,6 +73,41 @@
     def render(self):
         return u'go to @@version or @@secnotes'
 
+
+class AdminViewBase(grok.View):
+    """A grok.View with a special application_url.
+
+    We have to compute the application_url different from common
+    grok.Views, because we have no root application object in the
+    adminUI. To avoid mismatch, we also call it 'root_url'.
+
+    """
+    grok.baseclass()
+    
+    @property
+    def grok_version(self):
+        return getVersion('grok')
+
+    @property
+    def grokuiadmin_version(self):
+        return getVersion('grokui.admin')
+
+    def is_authenticated(self):
+        """Check, wether we are authenticated.
+        """
+        return not IUnauthenticatedPrincipal.providedBy(self.request.principal)
+
+    def root_url(self, name=None):
+        obj = self.context
+        result = ""
+        while obj is not None:
+            if IRootFolder.providedBy(obj):
+                return self.url(obj, name)
+            obj = obj.__parent__
+        raise ValueError("No application nor root element found.")
+
+
+
 class GrokAdminVersion(GrokCoreViewOrCodeView):
     """Display version of a package.
 
@@ -99,6 +122,7 @@
     def render(self, pkg='grok'):
         return u'%s %s' % (pkg, getVersion(pkg))
 
+
 class GrokAdminSecurityNotes(GrokCoreViewOrCodeView):
     """Display current security notification.
 
@@ -112,7 +136,8 @@
         site_manager = site.getSiteManager()
         notifier = site_manager.queryUtility(ISecurityNotifier, default=None)
         return notifier.getNotification()
-    
+
+
 class Add(GrokCoreViewOrCodeView):
     """Add an application.
     """
@@ -200,57 +225,8 @@
         self.redirect(self.url(self.context))
 
 
-class GAIAViewBase(object):
-    """A grok.View with a special application_url.
 
-    We have to compute the application_url different from common
-    grok.Views, because we have no root application object in the
-    adminUI. To avoid mismatch, we also call it 'root_url'.
-
-    """
-
-    @property
-    def grok_version(self):
-        return getVersion('grok')
-
-    @property
-    def grokuiadmin_version(self):
-        return getVersion('grokui.admin')
-
-    def root_url(self, name=None):
-        obj = self.context
-        result = ""
-        while obj is not None:
-            if IRootFolder.providedBy(obj):
-                return self.url(obj, name)
-            obj = obj.__parent__
-        raise ValueError("No application nor root element found.")
-
-    def in_docgrok(self):
-        return '/docgrok/' in self.url() or 'inspect.html' in self.url()
-
-    def is_authenticated(self):
-        """Check, wether we are authenticated.
-        """
-        return not IUnauthenticatedPrincipal.providedBy(self.request.principal)
-
-
-class GAIAView(GAIAViewBase, grok.View):
-    """ Base Class for grok.View"""
-    grok.baseclass()
-
-
-class GAIACodeView(GAIAViewBase, GrokCoreViewOrCodeView):    
-    """ Base Class for grokcore.view.CodeView"""
-    grok.baseclass()
-
-class GrokAdminMacros(GAIAView):
-    """Provides the o-wrap layout."""
-
-    grok.context(Interface)
-
-
-class Rename(GAIAView):
+class Rename(AdminViewBase):
     """Rename Grok applications.
     """
     grok.name('grokadmin_rename')
@@ -291,141 +267,10 @@
         self.redirect(self.url(self.context))
         return
 
-class Inspect(GAIAView):
-    """Basic object browser.
-    """
 
-    grok.context(Interface)
-    grok.name(u'inspect.html')
-    grok.require('grok.ManageApplications')
-
-    _metadata = None
-
-    def update(self, show_private=False, *args, **kw):
-        obj = self.context
-        if isinstance(self.context, ZopeObjectInfo):
-            # When the docgrok-object traverser delivers content, then
-            # we get a wrapped context: the meant object is wrapped
-            # into a ZopeObjectInfo.
-            obj = self.context.obj
-
-        self.ob_info = ZopeObjectInfo(obj)
-        ob_info = self.ob_info
-        self.show_private = show_private
-        root_url = self.root_url()
-        parent = ob_info.getParent()
-        parent = {'class_link':
-                      parent and getPathLinksForObject(parent) or '',
-                  'obj_link' : getItemLink('',getParentURL(self.url(''))),
-                  'obj' : parent
-                  }
-        bases = [getPathLinksForClass(x) for x in ob_info.getBases()]
-        bases.sort()
-
-        ifaces = [getPathLinksForClass(x) for x in
-                  ob_info.getProvidedInterfaces()]
-        ifaces.sort()
-
-        methods = [x for x in list(ob_info.getMethods())
-                   if self.show_private or not x['name'].startswith('_')]
-        for method in methods:
-            if method['interface']:
-                method['interface'] = getPathLinksForDottedName(
-                    method['interface'], root_url)
-            if method['doc']:
-                method['doc'] = renderText(method['doc'], getattr(
-                        obj,'__module__', None))
-
-        attrs = [x for x in list(ob_info.getAttributes())
-                 if self.show_private or not x['name'].startswith('_')
-                 ]
-        for attr in attrs:
-            if '.' in str(attr['type']):
-                attr['type'] = getPathLinksForClass(attr['type'], root_url)
-            else:
-                attr['type'] = attrEscape(str(attr['type']))
-            if attr['interface']:
-                attr['interface'] = getPathLinksForDottedName(
-                    attr['interface'], root_url)
-            attr['obj'] = getattr(obj, attr['name'], None)
-            attr['docgrok_link'] = getItemLink(attr['name'], self.url(''))
-        attrs.sort(lambda x,y: x['name']>y['name'])
-
-        seqitems = ob_info.getSequenceItems() or []
-        for item in seqitems:
-            if '.' in str(item['value_type']):
-                item['value_type'] = getPathLinksForClass(item['value_type'],
-                                                          root_url)
-            else:
-                item['value_type'] = attrEscape(str(item['value_type']))
-            item['obj'] = obj[item['index']]
-            item['docgrok_link'] = getItemLink(item['index'], self.url(''))
-        seqitems.sort()
-
-        mapitems = [x for x in ob_info.getMappingItems()
-                    if self.show_private or not x['key'].startswith('_')]
-        for item in mapitems:
-            if '.' in str(item['value_type']):
-                item['value_type'] = getPathLinksForClass(item['value_type'],
-                                                          root_url)
-            else:
-                item['value_type'] = attrEscape(str(item['value_type']))
-            item['obj'] = obj[item['key']]
-            item['docgrok_link'] = getItemLink(item['key'], self.url(''))
-        mapitems.sort(lambda x,y: x['key']>y['key'])
-
-        annotations = [x for x in ob_info.getAnnotationsInfo()
-                    if self.show_private or not x['key'].startswith('_')]
-        for item in annotations:
-            if '.' in str(item['value_type']):
-                item['value_type'] = getPathLinksForClass(item['value_type'],
-                                                          root_url)
-            else:
-                item['value_type'] = attrEscape(str(item['value_type']))
-            item['docgrok_link'] = getItemLink(item['key'], self.url(''))
-        annotations.sort(lambda x,y: x['key']>y['key'])
-
-
-        self.info = {
-            'name' : ob_info.getId() or u'<unnamed object>',
-            'type' : getPathLinksForClass((getattr(obj,
-                                                   '__class__',
-                                                   None)
-                                           or type(obj)), root_url),
-            'obj_link' : getPathLinksForObject(obj, root_url),
-            'moduleinfo' : ob_info.getmoduleinfo(),
-            'modulename' : ob_info.getmodulename(),
-            'ismodule' : ob_info.ismodule(),
-            'isclass' : ob_info.isclass(),
-            'ismethod' : ob_info.ismethod(),
-            'isfunction' : ob_info.isfunction(),
-            'iscode' : ob_info.iscode(),
-            'isbuiltin' : ob_info.isbuiltin(),
-            'isroutine' : ob_info.isroutine(),
-            'issequence' : ob_info.isSequence(),
-            'ismapping' : ob_info.isMapping(),
-            'isannotatable' : ob_info.isAnnotatable(),
-            'doc' : renderText(ob_info.getdoc(),None),
-            'comments' : ob_info.getcomments(),
-            'module' : ob_info.getmodule(),
-            'sourcefile' : ob_info.getsourcefile(),
-            'source' : ob_info.getsource(),
-            'parent' : parent,
-            'dotted_path' : ob_info.getPythonPath(),
-            'provided_interfaces' : ob_info.getDirectlyProvidedInterfaces(),
-            'interfaces' : ifaces,
-            'bases' : bases,
-            'attributes' : attrs,
-            'methods' : methods,
-            'sequenceitems' : seqitems,
-            'mappingitems' : mapitems,
-            'annotations' : annotations
-            }
-
-
-class Index(GAIAView):
-    """A redirector to the real frontpage."""
-
+class Index(AdminViewBase):
+    """A redirector to the real frontpage.
+    """
     grok.name('index.html') # The root folder is not a grok.Model
     grok.require('grok.ManageApplications')
 
@@ -438,20 +283,12 @@
         self.redirect(self.url('applications'))
 
 
-class Applications(GAIAView):
+class Applications(AdminViewBase):
     """View for application management.
-
     """
-
     grok.name('applications')
     grok.require('grok.ManageApplications')
 
-    def getDocOfApp(self, apppath, headonly = True):
-        doctor = docgrok.docgrok_handle(apppath)
-        result = doctor.getDoc(headonly)
-        if result is None:
-            result = ""
-        return result
 
     def update(self):
         from ZODB import broken
@@ -504,9 +341,16 @@
             raise KeyError(message)
 
 
-class Server(GAIAView, ZODBControlView):
-    """Zope3 management screen."""
+class GrokAdminMacros(AdminViewBase):
+    """Provides the o-wrap layout."""
 
+    grok.context(Interface)
+
+
+
+class Server(AdminViewBase, ZODBControlView):
+    """Zope3 management screen.
+    """
     grok.require('grok.ManageApplications')
 
     @property
@@ -630,9 +474,9 @@
             flash('ERROR packing ZODB `%s`: %s' % (dbName, err))
 
 
-class Users(GAIAView):
-    """Users management screen."""
-
+class Users(AdminViewBase):
+    """Users management screen.
+    """
     grok.name('users')
     grok.require('grok.ManageApplications')
 
@@ -653,232 +497,3 @@
     def update(self):
         self.principals = self.getPrincipals()
         pass
-
-
-
-def getDottedPathDict(dotted_path):
-    """Get a dict containing parts of a dotted path as links.
-    """
-    if dotted_path is None:
-        return {}
-
-    result = []
-    part_path = ""
-    for part in dotted_path.split('.'):
-        name = part
-        if part_path != "":
-            name = "." + part
-        part_path += part
-        result.append({
-            'name':name,
-            'url':"/docgrok/%s" % (part_path,)
-            })
-        part_path += "/"
-    return result
-
-
-class DocGrokView(GAIAView):
-    """A base DocGrok view.
-
-    This view is used for all things not covered by other, more
-    specialized views.
-    """
-
-    grok.context(DocGrok)
-    grok.name('index')
-    grok.require('grok.ManageApplications')
-
-    def getDoc(self, text=None, heading_only=False):
-        """Get the doc string of the module STX formatted."""
-        if text is None:
-            return None
-            if (hasattr(self.context, "apidoc") and
-                hasattr(self.context.apidoc, "getDocString")):
-                text = self.context.apidoc.getDocString()
-            else:
-                return None
-        lines = text.strip().split('\n')
-        if len(lines) and heading_only:
-            # Find first empty line to separate heading from trailing text.
-            headlines = []
-            for line in lines:
-                if line.strip() == "":
-                    break
-                headlines.append(line)
-            lines = headlines
-        # Get rid of possible CVS id.
-        lines = [line for line in lines if not line.startswith('$Id')]
-        return renderText('\n'.join(lines), self.context.getPath())
-
-    def getDocHeading(self, text=None):
-        return self.getDoc(text, True)
-
-    def getPathParts(self, path=None):
-        """Get parts of a dotted name as url and name parts.
-        """
-        if path is None:
-            path = self.context.path
-        if path is None:
-            return None
-        return getDottedPathDict(path)
-        result = []
-        part_path = ""
-        for part in path.split('.'):
-            name = part
-            if part_path != "":
-                name = "." + part
-            part_path += part
-            result.append({
-                'name':name,
-                'url':"/docgrok/%s" % (part_path,)
-                })
-            part_path += "/"
-        return result
-
-    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
-
-    def update(self):
-        self.docgrok_root = self.context._traversal_root
-        self.app_root = self.docgrok_root.__parent__
-        pass
-
-
-class DocGrokPackageView(DocGrokView):
-    """A view for packages handled by DocGrok."""
-
-    grok.context(DocGrokPackage)
-    grok.name('index')
-
-
-class DocGrokModuleView(DocGrokView):
-    """A view for modules handled by DocGrok."""
-
-    grok.context(DocGrokModule)
-    grok.name('index')
-
-
-class DocGrokClassView(DocGrokView):
-    """A view for classes handled by DocGrok."""
-
-    grok.context(DocGrokClass)
-    grok.name('index')
-
-    def getBases(self):
-        return self._listClasses(self.context.apidoc.getBases())
-
-    def getInterfaces(self):
-        return self._listClasses(
-          [iface for iface in self.context.apidoc.getInterfaces()])
-
-    def getAttributes(self):
-        attrs = self.context.getAttributes()
-        for a in attrs:
-            a['interface'] = self._listClasses([a['interface']])
-        return attrs
-
-    def getMethods(self):
-        methods = self.context.getMethods()
-        for m in methods:
-            m['doc'] = renderText(m['attr'].__doc__ or '',
-                                  inspect.getmodule(m['attr']))
-            m['interface'] = self._listClasses([m['interface']])
-        return methods
-
-    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
-
-
-class DocGrokInterfaceView(DocGrokClassView):
-
-    grok.context(DocGrokInterface)
-    grok.name('index')
-
-
-class DocGrokGrokApplicationView(DocGrokClassView):
-
-    grok.context(DocGrokGrokApplication)
-    grok.name('index')
-
-
-class DocGrokTextFileView(DocGrokView):
-
-    grok.context(DocGrokTextFile)
-    grok.name('index')
-
-    def getContent(self):
-        lines = self.context.getContent()
-        if self.context.path.endswith('.stx'):
-            format = 'zope.source.stx'
-        else:
-            format = 'zope.source.rest'
-        return renderText(lines, format=format)
-
-    def getPackagePathParts(self):
-        return self.getPathParts(
-            self.context.getPackagePath())

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/applications.pt
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/applications.pt	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/applications.pt	2009-09-14 22:26:34 UTC (rev 103985)
@@ -20,12 +20,8 @@
 				 name string:items" />
 	  <a tal:attributes="href string:${context/@@absolute_url}/${app/__name__}">
 	    <span tal:replace="app/__name__"/>
-	    (<span tal:replace="app/__class__/__name__"/>)
 	  </a>
-	  &nbsp;&nbsp;
-	  [<a href=""
-	      tal:attributes="href string:${context/@@absolute_url}/${app/__name__}/@@inspect.html"
-	      >object browser</a>]
+	    (<span tal:replace="app/__module__"/>.<span tal:replace="app/__class__/__name__"/>)
 	</div>
 
 	<div tal:condition="view/broken_applications">
@@ -60,13 +56,13 @@
 	<form action="" tal:attributes="action string:${context/@@absolute_url}/add;
                                         name python: app['name'].split('.')[-1]">
 	  <div class="menu-box2">
-	    <div class="menu-head1"><a href=""
-				       tal:attributes="href string:${context/@@absolute_url}/docgrok/${app/docurl}"
-				       tal:content="app/name">Application Name</a></div>
+	    <div class="menu-head1">
+	      <h3 tal:content="app/name">Application Name</h3>
+	    </div>
 	    <div class="menu-description1">
-	      <span tal:replace="structure python: view.getDocOfApp(app['name']) or ''">
+	      <p tal:replace="structure app/name/__doc__">
 		Application description here.
-	      </span>
+	      </p>
 	    </div>
 	    <div class="menu-box3">
 	      <label>Name your new app: <input type="text" name="name"/></label>

Modified: grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/grokadminmacros.pt
===================================================================
--- grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/grokadminmacros.pt	2009-09-14 22:08:13 UTC (rev 103984)
+++ grokui.admin/branches/introspectorless/src/grokui/admin/view_templates/grokadminmacros.pt	2009-09-14 22:26:34 UTC (rev 103985)
@@ -71,12 +71,6 @@
             Server Control
           </span>
         </span>
-        &nbsp;&nbsp;
-        <a href=""
-          tal:attributes="href string:${view/root_url}/docgrok/">
-          <span tal:attributes="class python:view.in_docgrok() and 'emph'"
-            >Documentation</span>
-        </a>
       </div>
 
         <div id="content">



More information about the checkins mailing list