[Checkins] SVN: Sandbox/faassen/grokcore.site/trunk/src/grokcore/ Move everything into site subpackage.
Martijn Faassen
faassen at infrae.com
Fri Oct 17 13:02:25 EDT 2008
Log message for revision 92328:
Move everything into site subpackage.
Changed:
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftests/
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftests/
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/tests/
A Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/tests/
D Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py
-=-
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,87 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grok
-"""
-from zope.interface import implements
-from zope.component import adapts
-
-from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
-from martian import baseclass
-from martian.error import GrokError, GrokImportError
-
-from grokcore.component import Adapter, MultiAdapter, GlobalUtility, Context
-from grokcore.component.decorators import subscribe, adapter, implementer
-from grokcore.component.directive import (
- context, name, title, description, provides, global_utility, direct)
-
-from grokcore.security import Permission
-from grokcore.security import Public
-from grokcore.security import require
-
-from grokcore.view import PageTemplate
-from grokcore.view import PageTemplateFile
-from grokcore.view import DirectoryResource
-from grokcore.view import layer
-from grokcore.view import template
-from grokcore.view import templatedir
-from grokcore.view import skin
-from grokcore.view import url
-from grokcore.view import path
-
-from grokcore.formlib import action
-from grokcore.formlib import AutoFields
-from grokcore.formlib import Fields
-
-from zope.event import notify
-from zope.app.component.hooks import getSite
-from zope.lifecycleevent import (
- IObjectCreatedEvent, ObjectCreatedEvent,
- IObjectModifiedEvent, ObjectModifiedEvent,
- IObjectCopiedEvent, ObjectCopiedEvent)
-
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-
-from zope.app.container.contained import (
- IObjectAddedEvent, ObjectAddedEvent,
- IObjectMovedEvent, ObjectMovedEvent,
- IObjectRemovedEvent, ObjectRemovedEvent,
- IContainerModifiedEvent, ContainerModifiedEvent)
-
-from grok.components import Model, View
-from grok.components import XMLRPC, REST, JSON
-from grok.components import Traverser
-from grok.components import Container, OrderedContainer
-from grok.components import Site, LocalUtility, Annotation
-from grok.components import Application, Form, AddForm, EditForm, DisplayForm
-from grok.components import Indexes
-from grok.components import Role
-from grok.components import RESTProtocol, IRESTLayer
-from grok.interfaces import IRESTSkinType
-from grok.components import ViewletManager, Viewlet
-
-from grok.directive import (local_utility, permissions, site,
- viewletmanager, view, traversable, order)
-
-
-
-# BBB These two functions are meant for test fixtures and should be
-# imported from grok.testing, not from grok.
-from grok.testing import grok, grok_component
-
-# Our __init__ provides the grok API directly so using 'import grok' is enough.
-from grok.interfaces import IGrokAPI
-from zope.interface import moduleProvides
-moduleProvides(IGrokAPI)
-__all__ = list(IGrokAPI)
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,402 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grok components"""
-
-import persistent
-import simplejson
-
-import zope.location
-from zope import component
-from zope import interface
-from zope.securitypolicy.role import Role
-from zope.publisher.browser import BrowserPage
-from zope.publisher.interfaces import NotFound
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.publisher.publish import mapply
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-from zope.app.publisher.browser import getDefaultViewName
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-from zope.app.container.interfaces import IReadContainer, IObjectAddedEvent
-from zope.app.container.interfaces import IOrderedContainer
-from zope.app.container.contained import notifyContainerModified
-from persistent.list import PersistentList
-from zope.app.component.site import SiteManagerContainer
-from zope.app.component.site import LocalSiteManager
-
-from zope.viewlet.manager import ViewletManagerBase
-from zope.viewlet.viewlet import ViewletBase
-
-import grok
-import z3c.flashmessage.interfaces
-import martian.util
-
-import grokcore.view
-import grokcore.formlib
-from grok import interfaces, util
-
-
-class Model(Contained, persistent.Persistent):
- # XXX Inheritance order is important here. If we reverse this,
- # then containers can't be models anymore because no unambigous MRO
- # can be established.
- interface.implements(IAttributeAnnotatable, interfaces.IContext)
-
-
-class Container(BTreeContainer):
- interface.implements(IAttributeAnnotatable, interfaces.IContainer)
-
-
-class OrderedContainer(Container):
- interface.implements(IOrderedContainer)
-
- def __init__(self):
- super(OrderedContainer, self).__init__()
- self._order = PersistentList()
-
- def keys(self):
- # Return a copy of the list to prevent accidental modifications.
- return self._order[:]
-
- def __iter__(self):
- return iter(self.keys())
-
- def values(self):
- return (self[key] for key in self._order)
-
- def items(self):
- return ((key, self[key]) for key in self._order)
-
- def __setitem__(self, key, object):
- foo = self.has_key(key)
- # Then do whatever containers normally do.
- super(OrderedContainer, self).__setitem__(key, object)
- if not foo:
- self._order.append(key)
-
- def __delitem__(self, key):
- # First do whatever containers normally do.
- super(OrderedContainer, self).__delitem__(key)
- self._order.remove(key)
-
- def updateOrder(self, order):
- if set(order) != set(self._order):
- raise ValueError("Incompatible key set.")
-
- self._order = PersistentList()
- self._order.extend(order)
- notifyContainerModified(self)
-
-
-class Site(SiteManagerContainer):
- pass
-
- at component.adapter(Site, IObjectAddedEvent)
-def addSiteHandler(site, event):
- sitemanager = LocalSiteManager(site)
- # LocalSiteManager creates the 'default' folder in its __init__.
- # It's not needed anymore in new versions of Zope 3, therefore we
- # remove it
- del sitemanager['default']
- site.setSiteManager(sitemanager)
-
-
-class Application(Site):
- """A top-level application object."""
- interface.implements(interfaces.IApplication)
-
-
-class LocalUtility(Model):
- pass
-
-
-class Annotation(persistent.Persistent):
- pass
-
-
-class View(grokcore.view.View):
- interface.implements(interfaces.IGrokView)
-
- def application_url(self, name=None):
- obj = self.context
- while obj is not None:
- if isinstance(obj, Application):
- return self.url(obj, name)
- obj = obj.__parent__
- raise ValueError("No application found.")
-
- def flash(self, message, type='message'):
- source = component.getUtility(
- z3c.flashmessage.interfaces.IMessageSource, name='session')
- source.send(message, type)
-
-
-class Form(grokcore.formlib.Form, View):
- interface.implements(interfaces.IGrokForm)
-
-
-class AddForm(grokcore.formlib.AddForm, View):
- interface.implements(interfaces.IGrokForm)
-
-
-class DisplayForm(grokcore.formlib.DisplayForm, View):
- interface.implements(interfaces.IGrokForm)
-
-
-class EditForm(grokcore.formlib.EditForm, View):
- interface.implements(interfaces.IGrokForm)
-
-
-class XMLRPC(object):
- pass
-
-class REST(zope.location.Location):
- interface.implements(interfaces.IREST)
-
- def __init__(self, context, request):
- self.context = self.__parent__ = context
- self.request = request
- self.body = request.bodyStream.getCacheStream().read()
-
- @property
- def response(self):
- return self.request.response
-
-## def GET(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def POST(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def PUT(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-## def DELETE(self):
-## raise GrokMethodNotAllowed(self.context, self.request)
-
-class JSON(BrowserPage):
-
- def __call__(self):
- view_name = self.__view_name__
- method = getattr(self, view_name)
- method_result = mapply(method, (), self.request)
- return simplejson.dumps(method_result)
-
-
-class Traverser(object):
- interface.implements(IBrowserPublisher)
-
- def __init__(self, context, request):
- self.context = context
- self.request = request
-
- def browserDefault(self, request):
- # if we have a RESTful request, we will handle
- # GET, POST and HEAD differently (PUT and DELETE are handled already
- # but not on the BrowserRequest layer but the HTTPRequest layer)
- if IRESTLayer.providedBy(request):
- rest_view = component.getMultiAdapter(
- (self.context, self.request),
- name=request.method)
- return rest_view, ()
- view_name = getDefaultViewName(self.context, request)
- view_uri = "@@%s" % view_name
- return self.context, (view_uri,)
-
- def publishTraverse(self, request, name):
- subob = self.traverse(name)
- if subob is not None:
- return util.safely_locate_maybe(subob, self.context, name)
-
- traversable_dict = grok.traversable.bind().get(self.context)
- if traversable_dict:
- if name in traversable_dict:
- subob = getattr(self.context, traversable_dict[name])
- if callable(subob):
- subob = subob()
- return util.safely_locate_maybe(subob, self.context, name)
-
- # XXX Special logic here to deal with containers. It would be
- # good if we wouldn't have to do this here. One solution is to
- # rip this out and make you subclass ContainerTraverser if you
- # wanted to override the traversal behaviour of containers.
- if IReadContainer.providedBy(self.context):
- item = self.context.get(name)
- if item is not None:
- return item
-
- view = component.queryMultiAdapter((self.context, request), name=name)
- if view is not None:
- return view
-
- raise NotFound(self.context, name, request)
-
- def traverse(self, name):
- # this will be overridden by subclasses
- pass
-
-
-class ContextTraverser(Traverser):
- component.adapts(interfaces.IContext, IHTTPRequest)
-
- def traverse(self, name):
- traverse = getattr(self.context, 'traverse', None)
- if traverse:
- return traverse(name)
-
-
-class ContainerTraverser(Traverser):
- component.adapts(interfaces.IContainer, IHTTPRequest)
-
- def traverse(self, name):
- traverse = getattr(self.context, 'traverse', None)
- if traverse:
- result = traverse(name)
- if result is not None:
- return result
- # try to get the item from the container
- return self.context.get(name)
-
-
-class IndexesClass(object):
- def __init__(self, name, bases=(), attrs=None):
- if attrs is None:
- return
- indexes = {}
- for name, value in attrs.items():
- # Ignore everything that's not an index definition object
- # except for values set by directives
- if '.' in name:
- setattr(self, name, value)
- continue
- if not interfaces.IIndexDefinition.providedBy(value):
- continue
- indexes[name] = value
- self.__grok_indexes__ = indexes
- # __grok_module__ is needed to make defined_locally() return True for
- # inline templates
- self.__grok_module__ = martian.util.caller_module()
-
-Indexes = IndexesClass('Indexes')
-
-
-class Role(Role):
- pass
-
-class IRESTLayer(IBrowserRequest):
- pass
-
-class RESTProtocol(object):
- pass
-
-class ViewletManager(ViewletManagerBase):
- interface.implements(interfaces.IViewletManager)
-
- template = None
-
- def __init__(self, context, request, view):
- super(ViewletManager, self).__init__(context, request, view)
- self.context = context
- self.request = request
- self.view = view
- self.__name__ = self.__view_name__
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
- def sort(self, viewlets):
- """Sort the viewlets.
-
- ``viewlets`` is a list of tuples of the form (name, viewlet).
- """
- # In Grok, the default order of the viewlets is determined by
- # util.sort_components. util.sort_components() however expects
- # a list of just components, but sort() is supposed to deal
- # with a list of (name, viewlet) tuples.
- # To handle this situation we first store the name part on the
- # viewlet, then use util.sort_components() and then "unpack"
- # the name from the viewlet and recreate the list of (name,
- # viewlet) tuples, now in the correct order.
- s_viewlets = []
- for name, viewlet in viewlets:
- # Stuff away viewlet name so we can later retrieve it.
- # XXX We loose name information in case the same viewlet
- # is in the viewlets list twice, but with a different
- # name. Most probably this situation doesn't occur.
- viewlet.__viewlet_name__ = name
- s_viewlets.append(viewlet)
- s_viewlets = util.sort_components(s_viewlets)
- return [(viewlet.__viewlet_name__, viewlet) for viewlet in s_viewlets]
-
- def default_namespace(self):
- namespace = {}
- namespace['context'] = self.context
- namespace['request'] = self.request
- namespace['static'] = self.static
- namespace['view'] = self.view
- namespace['viewletmanager'] = self
- return namespace
-
- def namespace(self):
- return {}
-
- def render(self):
- """See zope.contentprovider.interfaces.IContentProvider"""
- # Now render the view
- if self.template:
- return self.template.render(self)
- else:
- return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
-
-
-class Viewlet(ViewletBase):
- """Batteries included viewlet.
- """
-
- def __init__(self, context, request, view, manager):
- super(Viewlet, self).__init__(context, request, view, manager)
- self.context = context
- self.request = request
- self.view = view
- self.viewletmanager = manager
- self.__name__ = self.__view_name__
- self.static = component.queryAdapter(
- self.request,
- interface.Interface,
- name=self.module_info.package_dotted_name
- )
-
- def default_namespace(self):
- namespace = {}
- namespace['context'] = self.context
- namespace['request'] = self.request
- namespace['static'] = self.static
- namespace['view'] = self.view
- namespace['viewlet'] = self
- namespace['viewletmanager'] = self.manager
- return namespace
-
- def namespace(self):
- return {}
-
- def update(self):
- pass
-
- def render(self):
- return self.template.render(self)
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,84 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- xmlns:grok="http://namespaces.zope.org/grok">
-
- <include package="zope.security" file="meta.zcml" />
- <include package="zope.i18n" file="meta.zcml" />
- <include package="zope.securitypolicy" file="meta.zcml" />
- <include package="zope.app.zcmlfiles" file="meta.zcml" />
- <include package="grok" file="meta.zcml" />
-
- <include package="zope.annotation" />
- <include package="zope.copypastemove" />
- <include package="zope.contentprovider" />
- <include package="zope.formlib" />
- <include package="zope.i18n.locales" />
- <include package="zope.publisher" />
- <include package="zope.securitypolicy" />
- <include package="zope.size" />
- <include package="zope.traversing" />
- <include package="zope.traversing.browser" />
- <include package="zope.app.zcmlfiles" />
- <include package="zope.app.authentication" />
- <include package="zope.app.intid" />
- <include package="zope.app.keyreference" />
- <include package="zope.app.catalog" />
- <include package="zope.app.renderer" />
- <include package="zope.app.session" />
-
- <include package="grokcore.view" />
- <include package="grokcore.formlib" />
-
- <securityPolicy
- component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
-
- <adapter factory=".components.ContextTraverser" />
- <adapter factory=".components.ContainerTraverser" />
-
- <browser:defaultView
- for=".interfaces.IContext"
- name="index"
- />
-
- <subscriber handler=".components.addSiteHandler" />
-
- <!-- we register a ++rest++ traversal namespace -->
- <adapter
- factory=".rest.rest_skin"
- for="* zope.publisher.interfaces.browser.IHTTPRequest"
- provides="zope.traversing.interfaces.ITraversable"
- name="rest"
- />
-
- <!-- this overrides Zope 3's publication factories because they have
- the same name; we also need to change the priority because of
- the ZCML discriminator -->
- <publisher
- name="XMLRPC"
- factory=".publication.GrokXMLRPCFactory"
- methods="POST"
- mimetypes="text/xml"
- priority="21"
- />
-
- <publisher
- name="BROWSER"
- factory=".publication.GrokBrowserFactory"
- methods="GET POST HEAD"
- mimetypes="*"
- priority="11"
- />
-
- <publisher
- name="HTTP"
- factory=".publication.GrokHTTPFactory"
- methods="*"
- mimetypes="*"
- priority="1"
- />
-
- <!-- need to grok this for some basic REST support -->
- <grok:grok package=".rest" />
-
-</configure>
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,143 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grok directives.
-"""
-
-import sys
-import grok
-from zope import interface
-from zope.interface.interfaces import IInterface
-from zope.interface.interface import TAGGED_DATA
-
-from zope.publisher.interfaces.browser import IBrowserView
-
-import martian
-from martian import util
-from martian.error import GrokImportError, GrokError
-from martian.directive import StoreOnce, StoreMultipleTimes
-from grokcore.component.scan import UnambiguousComponentScope
-from grok import components
-
-class local_utility(martian.Directive):
- scope = martian.CLASS
- store = martian.DICT
-
- def factory(self, factory, provides=None, name=u'',
- setup=None, public=False, name_in_container=None):
- if provides is not None and not IInterface.providedBy(provides):
- raise GrokImportError("You can only pass an interface to the "
- "provides argument of %s." % self.name)
-
- if provides is None:
- provides = grok.provides.bind().get(factory)
-
- if provides is None:
- if util.check_subclass(factory, grok.LocalUtility):
- baseInterfaces = interface.implementedBy(grok.LocalUtility)
- utilityInterfaces = interface.implementedBy(factory)
- provides = list(utilityInterfaces - baseInterfaces)
-
- if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
- raise GrokImportError(
- "Cannot determine which interface to use "
- "for utility registration of %r. "
- "It implements an interface that is a specialization "
- "of an interface implemented by grok.LocalUtility. "
- "Specify the interface by either using grok.provides "
- "on the utility or passing 'provides' to "
- "grok.local_utility." % factory, factory)
- else:
- provides = list(interface.implementedBy(factory))
-
- util.check_implements_one_from_list(provides, factory)
- provides = provides[0]
-
- if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
- raise GrokImportError(
- "Conflicting local utility registration %r. "
- "Local utilities are registered multiple "
- "times for interface %r and name %r." %
- (factory, provides, name), factory)
-
- info = LocalUtilityInfo(factory, provides, name, setup, public,
- name_in_container)
- return (provides, name), info
-
-
-class LocalUtilityInfo(object):
-
- _order = 0
-
- def __init__(self, factory, provides, name=u'',
- setup=None, public=False, name_in_container=None):
- self.factory = factory
- self.provides = provides
- self.name = name
- self.setup = setup
- self.public = public
- self.name_in_container = name_in_container
-
- self.order = LocalUtilityInfo._order
- LocalUtilityInfo._order += 1
-
- def __cmp__(self, other):
- # LocalUtilityInfos have an inherit sort order by which the
- # registrations take place.
- return cmp(self.order, other.order)
-
-
-class site(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- validate = martian.validateInterfaceOrClass
-
-class permissions(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- default = []
-
- def factory(*args):
- return args
-
-class OneInterfaceOrClassOnClassOrModule(martian.Directive):
- """Convenience base class. Not for public use."""
- scope = martian.CLASS_OR_MODULE
- store = martian.ONCE
- validate = martian.validateInterfaceOrClass
-
-class viewletmanager(OneInterfaceOrClassOnClassOrModule):
- scope = UnambiguousComponentScope('viewletmanager')
-
-class view(OneInterfaceOrClassOnClassOrModule):
- default = IBrowserView
-
-class traversable(martian.Directive):
- scope = martian.CLASS
- store = martian.DICT
-
- def factory(self, attr, name=None):
- if name is None:
- name = attr
- return (name, attr)
-
-class order(martian.Directive):
- scope = martian.CLASS
- store = martian.ONCE
- default = 0, 0
-
- _order = 0
-
- def factory(self, value=0):
- order._order += 1
- return value, order._order
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,35 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:grok="http://namespaces.zope.org/grok"
- i18n_domain="grok"
- package="grok"
- >
-
- <include package="grok" />
- <grok:grok package="grok.ftests" />
-
- <securityPolicy
- component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
- />
-
- <unauthenticatedPrincipal
- id="zope.anybody"
- title="Unauthenticated User"
- />
- <grant
- permission="zope.View"
- principal="zope.anybody"
- />
-
- <principal
- id="zope.mgr"
- title="Manager"
- login="mgr"
- password="mgrpw"
- />
-
- <role id="zope.Manager" title="Site Manager" />
- <grantAll role="zope.Manager" />
- <grant role="zope.Manager" principal="zope.mgr" />
-
-</configure>
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,75 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2007-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.
-#
-##############################################################################
-"""Grok index definitions
-"""
-import sys
-
-from zope.interface import implements
-from zope.interface.interfaces import IMethod, IInterface
-
-from zope.app.catalog.field import FieldIndex
-from zope.app.catalog.text import TextIndex
-from zc.catalog.catalogindex import SetIndex
-
-from martian.error import GrokError, GrokImportError
-from martian.util import frame_is_class
-
-from grok.interfaces import IIndexDefinition
-
-class IndexDefinition(object):
- implements(IIndexDefinition)
-
- index_class = None
-
- def __init__(self, *args, **kw):
- frame = sys._getframe(1)
- if not frame_is_class(frame):
- raise GrokImportError(
- "%r can only be instantiated on class level." % self.__class__)
- # store any extra parameters to pass to index later
- self._args = args
- self._attribute = kw.pop('attribute', None)
- self._kw = kw
-
- def setup(self, catalog, name, context, module_info):
- if self._attribute is not None:
- field_name = self._attribute
- else:
- field_name = name
-
- if IInterface.providedBy(context):
- try:
- method = context[field_name]
- except KeyError:
- raise GrokError("grok.Indexes in %r refers to an attribute or "
- "method %r on interface %r, but this does not "
- "exist." % (module_info.getModule(),
- field_name, context), None)
- call = IMethod.providedBy(method)
- else:
- call = callable(getattr(context, field_name, None))
- context = None # no interface lookup
- catalog[name] = self.index_class(field_name=field_name,
- interface=context,
- field_callable=call,
- *self._args, **self._kw)
-
-class Field(IndexDefinition):
- index_class = FieldIndex
-
-class Text(IndexDefinition):
- index_class = TextIndex
-
-class Set(IndexDefinition):
- index_class = SetIndex
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,234 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grok interfaces
-"""
-from zope import interface, schema
-from zope.formlib.interfaces import reConstraint
-from zope.interface.interfaces import IInterface
-from zope.viewlet.interfaces import IViewletManager as IViewletManagerBase
-from zope.app.container.interfaces import IContainer as IContainerBase
-
-import grokcore.component.interfaces
-import grokcore.formlib.interfaces
-import grokcore.security.interfaces
-import grokcore.view.interfaces
-
-# Expose interfaces from grokcore.* packages as well:
-from grokcore.component.interfaces import IContext
-from grokcore.component.interfaces import IGrokErrors
-from grokcore.view.interfaces import ITemplateFileFactory
-from grokcore.view.interfaces import ITemplate
-
-
-class IGrokBaseClasses(grokcore.component.interfaces.IBaseClasses,
- grokcore.security.interfaces.IBaseClasses,
- grokcore.view.interfaces.IBaseClasses):
- Model = interface.Attribute("Base class for persistent content objects "
- "(models).")
- Container = interface.Attribute("Base class for containers.")
- OrderedContainer = interface.Attribute("Base class for ordered containers.")
- Site = interface.Attribute("Mixin class for sites.")
- Application = interface.Attribute("Base class for applications.")
- Annotation = interface.Attribute("Base class for persistent annotations.")
- LocalUtility = interface.Attribute("Base class for local utilities.")
- XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
- JSON = interface.Attribute("Base class for JSON methods.")
- REST = interface.Attribute("Base class for REST views.")
- Traverser = interface.Attribute("Base class for custom traversers.")
- Indexes = interface.Attribute("Base class for catalog index definitions.")
- ViewletManager = interface.Attribute("Base class for viewletmanager.")
- Viewlet = interface.Attribute("Base class for viewlet.")
- Role = interface.Attribute("Base class for roles.")
-
-
-class IGrokDirectives(grokcore.component.interfaces.IDirectives,
- grokcore.security.interfaces.IDirectives,
- grokcore.view.interfaces.IDirectives):
-
- def local_utility(factory, provides=None, name=u'',
- setup=None, public=False, name_in_container=None):
- """Register a local utility.
-
- factory - the factory that creates the local utility
- provides - the interface the utility should be looked up with
- name - the name of the utility
- setup - a callable that receives the utility as its single argument,
- it is called after the utility has been created and stored
- public - if False, the utility will be stored below ++etc++site
- if True, the utility will be stored directly in the site.
- The site should in this case be a container.
- name_in_container - the name to use for storing the utility
- """
-
- def permissions(permissions):
- """Specify the permissions that comprise a role.
- """
-
- def site(class_or_interface):
- """Specifies the site that an indexes definition is for.
-
- It can only be used inside grok.Indexes subclasses.
- """
-
- def order(value=None):
- """Control the ordering of components.
-
- If the value is specified, the order will be determined by sorting on
- it.
- If no value is specified, the order will be determined by definition
- order within the module.
- If the directive is absent, the order will be determined by class name.
- (unfortunately our preferred default behavior on absence which would
- be like grok.order() without argument is hard to implement in Python)
-
- Inter-module order is by dotted name of the module the
- components are in; unless an explicit argument is specified to
- ``grok.order()``, components are grouped by module.
-
- The function grok.util.sort_components can be used to sort
- components according to these rules.
- """
-
-
-class IGrokEvents(interface.Interface):
-
- IObjectCreatedEvent = interface.Attribute("")
-
- ObjectCreatedEvent = interface.Attribute("")
-
- IObjectModifiedEvent = interface.Attribute("")
-
- ObjectModifiedEvent = interface.Attribute("")
-
- IObjectCopiedEvent = interface.Attribute("")
-
- ObjectCopiedEvent = interface.Attribute("")
-
- IObjectAddedEvent = interface.Attribute("")
-
- ObjectAddedEvent = interface.Attribute("")
-
- IObjectMovedEvent = interface.Attribute("")
-
- ObjectMovedEvent = interface.Attribute("")
-
- IObjectRemovedEvent = interface.Attribute("")
-
- ObjectRemovedEvent = interface.Attribute("")
-
- IContainerModifiedEvent = interface.Attribute("")
-
- ContainerModifiedEvent = interface.Attribute("")
-
-
-class IGrokAPI(grokcore.security.interfaces.IGrokcoreSecurityAPI,
- grokcore.view.interfaces.IGrokcoreViewAPI,
- grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
- IGrokBaseClasses, IGrokDirectives,
- IGrokEvents, IGrokErrors):
-
- # BBB this is deprecated
- def grok(dotted_name):
- """Grok a module or package specified by ``dotted_name``.
-
- NOTE: This function will be removed from the public Grok
- public API. For tests and interpreter sessions, use
- grok.testing.grok().
- """
-
- # BBB this is deprecated
- def grok_component(name, component, context=None, module_info=None,
- templates=None):
- """Grok an arbitrary object. Can be useful during testing.
-
- name - the name of the component (class name, or global instance name
- as it would appear in a module).
- component - the object (class, etc) to grok.
- context - the context object (optional).
- module_info - the module being grokked (optional).
- templates - the templates registry (optional).
-
- Note that context, module_info and templates might be required
- for some grokkers which rely on them.
-
- NOTE: This function will be removed from the public Grok
- public API. For tests and interpreter sessions, use
- grok.testing.grok_component().
- """
-
- def notify(event):
- """Send ``event`` to event subscribers."""
-
- def getSite():
- """Get the current site."""
-
-
- IRESTSkinType = interface.Attribute('The REST skin type')
-
-
-class IGrokView(grokcore.view.interfaces.IGrokView):
- """Grok views all provide this interface."""
-
- def application_url(name=None):
- """Return the URL of the closest application object in the
- hierarchy or the URL of a named object (``name`` parameter)
- relative to the closest application object.
- """
-
- def flash(message, type='message'):
- """Send a short message to the user."""
-
-
-class IGrokForm(grokcore.formlib.interfaces.IGrokForm, IGrokView):
- """All Grok forms provides this interface."""
-
-
-class IREST(interface.Interface):
- context = interface.Attribute("Object that the REST handler presents.")
-
- request = interface.Attribute("Request that REST handler was looked"
- "up with.")
-
- body = interface.Attribute(
- """The text of the request body.""")
-
-class IApplication(interface.Interface):
- """Marker-interface for grok application factories.
-
- Used to register applications as utilities to look them up and
- provide a list of grokked applications.
- """
-
-class IIndexDefinition(interface.Interface):
- """Define an index for grok.Indexes.
- """
-
- def setup(catalog, name, context):
- """Set up index called name in given catalog.
-
- Use name for index name and attribute to index. Set up
- index for interface or class context.
- """
-
-class IRESTSkinType(IInterface):
- """Skin type for REST requests.
- """
-
-class IContainer(IContext, IContainerBase):
- """A Grok container.
- """
-
-class IViewletManager(IViewletManagerBase):
- """The Grok viewlet manager.
- """
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,537 +0,0 @@
-#############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grokkers for the various components."""
-
-import zope.component.interface
-from zope import interface, component
-from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
- IBrowserRequest,
- IBrowserPublisher)
-from zope.publisher.interfaces.http import IHTTPRequest
-
-from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
-from zope.viewlet.interfaces import IViewletManager, IViewlet
-from zope.securitypolicy.interfaces import IRole
-from zope.securitypolicy.rolepermission import rolePermissionManager
-
-from zope.annotation.interfaces import IAnnotations
-
-from zope.app.publisher.xmlrpc import MethodPublisher
-from zope.app.container.interfaces import IContainer
-from zope.app.container.interfaces import INameChooser
-from zope.app.container.contained import contained
-
-from zope.app.intid import IntIds
-from zope.app.intid.interfaces import IIntIds
-from zope.app.catalog.catalog import Catalog
-from zope.app.catalog.interfaces import ICatalog
-
-from zope.exceptions.interfaces import DuplicationError
-
-import martian
-from martian.error import GrokError
-from martian import util
-
-import grok
-from grok import components
-from grok.util import make_checker
-from grok.interfaces import IRESTSkinType
-from grok.interfaces import IViewletManager as IGrokViewletManager
-
-from grokcore.component.scan import determine_module_component
-from grokcore.security.meta import PermissionGrokker
-
-from grokcore.view.meta.views import (
- default_view_name, default_fallback_to_name)
-
-
-def default_annotation_provides(factory, module, **data):
- base_interfaces = interface.implementedBy(grok.Annotation)
- factory_interfaces = interface.implementedBy(factory)
- real_interfaces = list(factory_interfaces - base_interfaces)
- util.check_implements_one_from_list(real_interfaces, factory)
- return real_interfaces[0]
-
-def default_annotation_name(factory, module, **data):
- return factory.__module__ + '.' + factory.__name__
-
-
-class ViewletManagerContextGrokker(martian.GlobalGrokker):
-
- martian.priority(1001)
-
- def grok(self, name, module, module_info, config, **kw):
- viewletmanager = determine_module_component(module_info,
- grok.viewletmanager,
- IGrokViewletManager)
- grok.viewletmanager.set(module, viewletmanager)
- return True
-
-
-class XMLRPCGrokker(martian.MethodGrokker):
- martian.component(grok.XMLRPC)
- martian.directive(grok.context)
- martian.directive(grok.require, name='permission')
-
- def execute(self, factory, method, config, context, permission, **kw):
- name = method.__name__
-
- # Make sure that the class inherits MethodPublisher, so that the
- # views have a location
- method_view = type(
- factory.__name__, (factory, MethodPublisher),
- {'__call__': method}
- )
-
- adapts = (context, IXMLRPCRequest)
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class RESTGrokker(martian.MethodGrokker):
- martian.component(grok.REST)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=grok.IRESTLayer)
- martian.directive(grok.require, name='permission')
-
- def execute(self, factory, method, config, permission, context, layer, **kw):
- name = method.__name__
-
- method_view = type(
- factory.__name__, (factory,),
- {'__call__': method }
- )
-
- adapts = (context, layer)
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class JSONGrokker(martian.MethodGrokker):
- martian.component(grok.JSON)
- martian.directive(grok.context)
- martian.directive(grok.require, name='permission')
-
- # TODO: this grokker doesn't support layers yet
-
- def execute(self, factory, method, config, context, permission, **kw):
- # Create a new class with a __view_name__ attribute so the
- # JSON class knows what method to call.
- method_view = type(
- factory.__name__, (factory,),
- {'__view_name__': method.__name__}
- )
- adapts = (context, IDefaultBrowserLayer)
- name = method.__name__
-
- config.action(
- discriminator=('adapter', adapts, interface.Interface, name),
- callable=component.provideAdapter,
- args=(method_view, adapts, interface.Interface, name),
- )
- config.action(
- discriminator=('protectName', method_view, '__call__'),
- callable=make_checker,
- args=(factory, method_view, permission),
- )
- return True
-
-
-class TraverserGrokker(martian.ClassGrokker):
- martian.component(grok.Traverser)
- martian.directive(grok.context)
-
- def execute(self, factory, config, context, **kw):
- adapts = (context, IHTTPRequest)
- config.action(
- discriminator=('adapter', adapts, IBrowserPublisher, ''),
- callable=component.provideAdapter,
- args=(factory, adapts, IBrowserPublisher),
- )
- return True
-
-
-class SiteGrokker(martian.ClassGrokker):
- martian.component(grok.Site)
- martian.priority(500)
- martian.directive(grok.local_utility, name='infos')
-
- def execute(self, factory, config, infos, **kw):
- if not infos:
- return False
-
- infos = infos.values()
- for info in infos:
- if info.public and not IContainer.implementedBy(factory):
- raise GrokError(
- "Cannot set public to True with grok.local_utility as "
- "the site (%r) is not a container." %
- factory, factory)
-
- # Store the list of info objects in their "natural" order on the
- # site class. They will be picked up by a subscriber doing the
- # actual registrations in definition order.
- factory.__grok_utilities_to_install__ = sorted(infos)
- adapts = (factory, grok.IObjectAddedEvent)
-
- config.action(
- discriminator=None,
- callable=component.provideHandler,
- args=(localUtilityRegistrationSubscriber, adapts),
- )
- return True
-
-
-def localUtilityRegistrationSubscriber(site, event):
- """A subscriber that fires to set up local utilities.
- """
- installed = getattr(site, '__grok_utilities_installed__', False)
- if installed:
- return
-
- for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
- setupUtility(site, info.factory(), info.provides, name=info.name,
- name_in_container=info.name_in_container,
- public=info.public, setup=info.setup)
-
- # we are done. If this subscriber gets fired again, we therefore
- # do not register utilities anymore
- site.__grok_utilities_installed__ = True
-
-
-def setupUtility(site, utility, provides, name=u'',
- name_in_container=None, public=False, setup=None):
- """Set up a utility in a site.
-
- site - the site to set up the utility in
- utility - the utility to set up
- provides - the interface the utility should be registered with
- name - the name the utility should be registered under, default
- the empty string (no name)
- name_in_container - if given it will be used to add the utility
- object to its container. Otherwise a name will be made up
- public - if False, the utility will be stored in the site manager. If
- True, the utility will be storedin the site (it is assumed the
- site is a container)
- setup - if not None, it will be called with the utility as its first
- argument. This function can then be used to further set up the
- utility.
- """
- site_manager = site.getSiteManager()
-
- if not public:
- container = site_manager
- else:
- container = site
-
- if name_in_container is None:
- name_in_container = INameChooser(container).chooseName(
- utility.__class__.__name__, utility)
- container[name_in_container] = utility
-
- if setup is not None:
- setup(utility)
-
- site_manager.registerUtility(utility, provided=provides,
- name=name)
-
-
-class RoleGrokker(martian.ClassGrokker):
- martian.component(grok.Role)
- martian.priority(martian.priority.bind().get(PermissionGrokker()) - 1)
- martian.directive(grok.name)
- martian.directive(grok.title, get_default=default_fallback_to_name)
- martian.directive(grok.description)
- martian.directive(grok.permissions)
-
- def execute(self, factory, config, name, title, description,
- permissions, **kw):
- if not name:
- raise GrokError(
- "A role needs to have a dotted name for its id. Use "
- "grok.name to specify one.", factory)
- # We can safely convert to unicode, since the directives makes sure
- # it is either unicode already or ASCII.
- role = factory(unicode(name), unicode(title), unicode(description))
-
- config.action(
- discriminator=('utility', IRole, name),
- callable=component.provideUtility,
- args=(role, IRole, name),
- )
-
- for permission in permissions:
- config.action(
- discriminator=('grantPermissionToRole', permission, name),
- callable=rolePermissionManager.grantPermissionToRole,
- args=(permission, name),
- )
- return True
-
-
-class AnnotationGrokker(martian.ClassGrokker):
- martian.component(grok.Annotation)
- martian.directive(grok.context, name='adapter_context')
- martian.directive(grok.provides, get_default=default_annotation_provides)
- martian.directive(grok.name, get_default=default_annotation_name)
-
- def execute(self, factory, config, adapter_context, provides, name, **kw):
- @component.adapter(adapter_context)
- @interface.implementer(provides)
- def getAnnotation(context):
- annotations = IAnnotations(context)
- try:
- result = annotations[name]
- except KeyError:
- result = factory()
- annotations[name] = result
-
- # Containment has to be set up late to allow containment
- # proxies to be applied, if needed. This does not trigger
- # an event and is idempotent if containment is set up
- # already.
- contained_result = contained(result, context, name)
- return contained_result
-
- config.action(
- discriminator=('adapter', adapter_context, provides, ''),
- callable=component.provideAdapter,
- args=(getAnnotation,),
- )
- return True
-
-
-class ApplicationGrokker(martian.ClassGrokker):
- martian.component(grok.Application)
- martian.priority(500)
-
- def grok(self, name, factory, module_info, config, **kw):
- # XXX fail loudly if the same application name is used twice.
- provides = grok.interfaces.IApplication
- name = '%s.%s' % (module_info.dotted_name, name)
- config.action(
- discriminator=('utility', provides, name),
- callable=component.provideUtility,
- args=(factory, provides, name),
- )
- return True
-
-
-class IndexesGrokker(martian.InstanceGrokker):
- martian.component(components.IndexesClass)
-
- def grok(self, name, factory, module_info, config, **kw):
- site = grok.site.bind().get(factory)
- context = grok.context.bind().get(factory, module_info.getModule())
- catalog_name = grok.name.bind().get(factory)
-
- if site is None:
- raise GrokError("No site specified for grok.Indexes "
- "subclass in module %r. "
- "Use grok.site() to specify."
- % module_info.getModule(),
- factory)
- indexes = getattr(factory, '__grok_indexes__', None)
- if indexes is None:
- return False
-
- subscriber = IndexesSetupSubscriber(catalog_name, indexes,
- context, module_info)
- subscribed = (site, grok.IObjectAddedEvent)
- config.action(
- discriminator=None,
- callable=component.provideHandler,
- args=(subscriber, subscribed),
- )
- return True
-
-
-class IndexesSetupSubscriber(object):
-
- def __init__(self, catalog_name, indexes, context, module_info):
- self.catalog_name = catalog_name
- self.indexes = indexes
- self.context = context
- self.module_info = module_info
-
- def __call__(self, site, event):
- # make sure we have an intids
- self._createIntIds(site)
- # get the catalog
- catalog = self._createCatalog(site)
- # now install indexes
- for name, index in self.indexes.items():
- try:
- index.setup(catalog, name, self.context, self.module_info)
- except DuplicationError:
- raise GrokError(
- "grok.Indexes in module %r causes "
- "creation of catalog index %r in catalog %r, "
- "but an index with that name is already present." %
- (self.module_info.getModule(), name, self.catalog_name),
- None)
-
- def _createCatalog(self, site):
- """Create the catalog if needed and return it.
-
- If the catalog already exists, return that.
-
- """
- catalog = zope.component.queryUtility(
- ICatalog, name=self.catalog_name, context=site, default=None)
- if catalog is not None:
- return catalog
- catalog = Catalog()
- setupUtility(site, catalog, ICatalog, name=self.catalog_name)
- return catalog
-
- def _createIntIds(self, site):
- """Create intids if needed, and return it.
- """
- intids = zope.component.queryUtility(
- IIntIds, context=site, default=None)
- if intids is not None:
- return intids
- intids = IntIds()
- setupUtility(site, intids, IIntIds)
- return intids
-
-
-class RESTProtocolGrokker(martian.ClassGrokker):
- martian.component(grok.RESTProtocol)
- martian.directive(grok.layer, default=IBrowserRequest)
- martian.directive(grok.name, get_default=default_view_name)
-
- def execute(self, factory, config, name, layer, **kw):
- config.action(
- discriminator=('restprotocol', name),
- callable=zope.component.interface.provideInterface,
- args=(name, layer, IRESTSkinType)
- )
- return True
-
-class ViewletManagerGrokker(martian.ClassGrokker):
- martian.component(grok.ViewletManager)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=IDefaultBrowserLayer)
- martian.directive(grok.view)
- martian.directive(grok.name)
-
- def grok(self, name, factory, module_info, **kw):
- # Need to store the module info object on the view class so that it
- # can look up the 'static' resource directory.
- factory.module_info = module_info
- return super(ViewletManagerGrokker, self).grok(
- name, factory, module_info, **kw)
-
- def execute(self, factory, config, context, layer, view, name, **kw):
- # This will be used to support __name__ on the viewlet manager
- factory.__view_name__ = name
-
- # find templates
- templates = factory.module_info.getAnnotation('grok.templates', None)
- if templates is not None:
- config.action(
- discriminator=None,
- callable=self.checkTemplates,
- args=(templates, factory.module_info, factory)
- )
-
- config.action(
- discriminator = ('viewletManager', context, layer, view, name),
- callable = component.provideAdapter,
- args = (factory, (context, layer, view), IViewletManager, name)
- )
- return True
-
- def checkTemplates(self, templates, module_info, factory):
- def has_render(factory):
- return factory.render != grok.components.ViewletManager.render
- def has_no_render(factory):
- # always has a render method
- return False
- templates.checkTemplates(module_info, factory, 'viewlet manager',
- has_render, has_no_render)
-
-class ViewletGrokker(martian.ClassGrokker):
- martian.component(grok.Viewlet)
- martian.directive(grok.context)
- martian.directive(grok.layer, default=IDefaultBrowserLayer)
- martian.directive(grok.view)
- martian.directive(grok.viewletmanager)
- martian.directive(grok.name, get_default=default_view_name)
- martian.directive(grok.require, name='permission')
-
- def grok(self, name, factory, module_info, **kw):
- # Need to store the module info object on the view class so that it
- # can look up the 'static' resource directory.
- factory.module_info = module_info
- return super(ViewletGrokker, self).grok(
- name, factory, module_info, **kw)
-
- def execute(self, factory, config,
- context, layer, view, viewletmanager, name, permission, **kw):
- # This will be used to support __name__ on the viewlet
- factory.__view_name__ = name
-
- # find templates
- templates = factory.module_info.getAnnotation('grok.templates', None)
- if templates is not None:
- config.action(
- discriminator=None,
- callable=self.checkTemplates,
- args=(templates, factory.module_info, factory)
- )
-
- config.action(
- discriminator = ('viewlet', context, layer,
- view, viewletmanager, name),
- callable = component.provideAdapter,
- args = (factory, (context, layer, view, viewletmanager),
- IViewlet, name)
- )
-
- config.action(
- discriminator=('protectName', factory, '__call__'),
- callable=make_checker,
- args=(factory, factory, permission, ['update', 'render']),
- )
-
- return True
-
- def checkTemplates(self, templates, module_info, factory):
- def has_render(factory):
- return factory.render != grok.components.Viewlet.render
- def has_no_render(factory):
- return not has_render(factory)
- templates.checkTemplates(module_info, factory, 'viewlet',
- has_render, has_no_render)
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,15 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:meta="http://namespaces.zope.org/meta"
- xmlns:grok="http://namespaces.zope.org/grok">
-
- <include package="z3c.autoinclude" file="meta.zcml" />
-
- <!-- Load the grokkers -->
- <include package="grokcore.component" file="meta.zcml" />
- <include package="grokcore.formlib" file="meta.zcml" />
- <include package="grokcore.security" file="meta.zcml" />
- <include package="grokcore.view" file="meta.zcml" />
- <grok:grok package=".meta" />
-
-</configure>
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,90 +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.
-#
-##############################################################################
-"""Grok publication objects
-"""
-
-from grok.rest import GrokMethodNotAllowed
-
-from zope import component
-from zope.security.proxy import removeSecurityProxy
-from zope.security.checker import selectChecker
-from zope.publisher.publish import mapply
-
-from zope.app.publication.http import BaseHTTPPublication, HTTPPublication
-from zope.app.publication.browser import BrowserPublication
-from zope.app.publication.requestpublicationfactories import \
- BrowserFactory, XMLRPCFactory, HTTPFactory
-from zope.app.http.interfaces import IHTTPException
-
-class ZopePublicationSansProxy(object):
-
- def getApplication(self, request):
- result = super(ZopePublicationSansProxy, self).getApplication(request)
- return removeSecurityProxy(result)
-
- def traverseName(self, request, ob, name):
- result = super(ZopePublicationSansProxy, self).traverseName(
- request, ob, name)
- return removeSecurityProxy(result)
-
- def callObject(self, request, ob):
- checker = selectChecker(ob)
- if checker is not None:
- checker.check(ob, '__call__')
- return super(ZopePublicationSansProxy, self).callObject(request, ob)
-
-
-class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
-
- def getDefaultTraversal(self, request, ob):
- obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
- request, ob)
- return removeSecurityProxy(obj), path
-
-
-class GrokBrowserFactory(BrowserFactory):
-
- def __call__(self):
- request, publication = super(GrokBrowserFactory, self).__call__()
- return request, GrokBrowserPublication
-
-
-class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
- pass
-
-class GrokXMLRPCFactory(XMLRPCFactory):
-
- def __call__(self):
- request, publication = super(GrokXMLRPCFactory, self).__call__()
- return request, GrokXMLRPCPublication
-
-
-class GrokHTTPPublication(ZopePublicationSansProxy, HTTPPublication):
- def callObject(self, request, ob):
- orig = ob
- if not IHTTPException.providedBy(ob):
- ob = component.queryMultiAdapter((ob, request),
- name=request.method)
- checker = selectChecker(ob)
- if checker is not None:
- checker.check(ob, '__call__')
- ob = getattr(ob, request.method, None)
- if ob is None:
- raise GrokMethodNotAllowed(orig, request)
- return mapply(ob, request.getPositionalArguments(), request)
-
-class GrokHTTPFactory(HTTPFactory):
- def __call__(self):
- request, publication = super(GrokHTTPFactory, self).__call__()
- return request, GrokHTTPPublication
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,86 +0,0 @@
-import grok
-
-from zope import component
-from zope.component.interfaces import ComponentLookupError
-
-from zope.traversing.interfaces import TraversalError
-from zope.traversing.namespace import view
-from zope.interface import Interface
-from zope.interface.interfaces import IInterface
-from zope.publisher.interfaces.browser import IBrowserRequest
-from zope.publisher.interfaces.http import IHTTPRequest
-from zope.app.publication.http import MethodNotAllowed
-
-from grok.interfaces import IRESTSkinType
-from zope.publisher.browser import applySkin
-
-class GrokMethodNotAllowed(MethodNotAllowed):
- pass
-
-class MethodNotAllowedView(grok.MultiAdapter):
- grok.adapts(GrokMethodNotAllowed, IHTTPRequest)
- grok.name('index.html')
- grok.implements(Interface)
-
- def __init__(self, error, request):
- self.error = error
- self.request = request
- self.allow = self._getAllow()
-
- def _getAllow(self):
- allow = []
- for method in ['GET', 'PUT', 'POST', 'DELETE']:
- view = component.queryMultiAdapter(
- (self.error.object, self.error.request),
- name=method)
- if view is not None:
- is_not_allowed = getattr(view, 'is_not_allowed', False)
- if not is_not_allowed:
- allow.append(method)
- allow.sort()
- return allow
-
- def __call__(self):
- self.request.response.setHeader('Allow', ', '.join(self.allow))
- self.request.response.setStatus(405)
- return 'Method Not Allowed'
-
-class rest_skin(view):
- """A rest skin.
-
- This used to be supported by zope.traversing but the change was backed out.
- We need it for our REST support.
- """
- def traverse(self, name, ignored):
- self.request.shiftNameToApplication()
- try:
- skin = component.getUtility(IRESTSkinType, name)
- except ComponentLookupError:
- raise TraversalError("++rest++%s" % name)
- applySkin(self.request, skin)
- return self.context
-
-
-class NotAllowedREST(grok.REST):
- """These are registered for everything by default to cause the correct
- errors.
-
- Any more specific REST view overrides this.
- """
- grok.layer(grok.IRESTLayer)
- grok.context(Interface)
-
- is_not_allowed = True
-
- def GET(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def POST(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def PUT(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
- def DELETE(self):
- raise GrokMethodNotAllowed(self.context, self.request)
-
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/__init__.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/__init__.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grok
+"""
+from zope.interface import implements
+from zope.component import adapts
+
+from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
+from martian import baseclass
+from martian.error import GrokError, GrokImportError
+
+from grokcore.component import Adapter, MultiAdapter, GlobalUtility, Context
+from grokcore.component.decorators import subscribe, adapter, implementer
+from grokcore.component.directive import (
+ context, name, title, description, provides, global_utility, direct)
+
+from grokcore.security import Permission
+from grokcore.security import Public
+from grokcore.security import require
+
+from grokcore.view import PageTemplate
+from grokcore.view import PageTemplateFile
+from grokcore.view import DirectoryResource
+from grokcore.view import layer
+from grokcore.view import template
+from grokcore.view import templatedir
+from grokcore.view import skin
+from grokcore.view import url
+from grokcore.view import path
+
+from grokcore.formlib import action
+from grokcore.formlib import AutoFields
+from grokcore.formlib import Fields
+
+from zope.event import notify
+from zope.app.component.hooks import getSite
+from zope.lifecycleevent import (
+ IObjectCreatedEvent, ObjectCreatedEvent,
+ IObjectModifiedEvent, ObjectModifiedEvent,
+ IObjectCopiedEvent, ObjectCopiedEvent)
+
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+from zope.app.container.contained import (
+ IObjectAddedEvent, ObjectAddedEvent,
+ IObjectMovedEvent, ObjectMovedEvent,
+ IObjectRemovedEvent, ObjectRemovedEvent,
+ IContainerModifiedEvent, ContainerModifiedEvent)
+
+from grok.components import Model, View
+from grok.components import XMLRPC, REST, JSON
+from grok.components import Traverser
+from grok.components import Container, OrderedContainer
+from grok.components import Site, LocalUtility, Annotation
+from grok.components import Application, Form, AddForm, EditForm, DisplayForm
+from grok.components import Indexes
+from grok.components import Role
+from grok.components import RESTProtocol, IRESTLayer
+from grok.interfaces import IRESTSkinType
+from grok.components import ViewletManager, Viewlet
+
+from grok.directive import (local_utility, permissions, site,
+ viewletmanager, view, traversable, order)
+
+
+
+# BBB These two functions are meant for test fixtures and should be
+# imported from grok.testing, not from grok.
+from grok.testing import grok, grok_component
+
+# Our __init__ provides the grok API directly so using 'import grok' is enough.
+from grok.interfaces import IGrokAPI
+from zope.interface import moduleProvides
+moduleProvides(IGrokAPI)
+__all__ = list(IGrokAPI)
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/components.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/components.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,402 @@
+##############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grok components"""
+
+import persistent
+import simplejson
+
+import zope.location
+from zope import component
+from zope import interface
+from zope.securitypolicy.role import Role
+from zope.publisher.browser import BrowserPage
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.publisher.publish import mapply
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+from zope.app.publisher.browser import getDefaultViewName
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.contained import Contained
+from zope.app.container.interfaces import IReadContainer, IObjectAddedEvent
+from zope.app.container.interfaces import IOrderedContainer
+from zope.app.container.contained import notifyContainerModified
+from persistent.list import PersistentList
+from zope.app.component.site import SiteManagerContainer
+from zope.app.component.site import LocalSiteManager
+
+from zope.viewlet.manager import ViewletManagerBase
+from zope.viewlet.viewlet import ViewletBase
+
+import grok
+import z3c.flashmessage.interfaces
+import martian.util
+
+import grokcore.view
+import grokcore.formlib
+from grok import interfaces, util
+
+
+class Model(Contained, persistent.Persistent):
+ # XXX Inheritance order is important here. If we reverse this,
+ # then containers can't be models anymore because no unambigous MRO
+ # can be established.
+ interface.implements(IAttributeAnnotatable, interfaces.IContext)
+
+
+class Container(BTreeContainer):
+ interface.implements(IAttributeAnnotatable, interfaces.IContainer)
+
+
+class OrderedContainer(Container):
+ interface.implements(IOrderedContainer)
+
+ def __init__(self):
+ super(OrderedContainer, self).__init__()
+ self._order = PersistentList()
+
+ def keys(self):
+ # Return a copy of the list to prevent accidental modifications.
+ return self._order[:]
+
+ def __iter__(self):
+ return iter(self.keys())
+
+ def values(self):
+ return (self[key] for key in self._order)
+
+ def items(self):
+ return ((key, self[key]) for key in self._order)
+
+ def __setitem__(self, key, object):
+ foo = self.has_key(key)
+ # Then do whatever containers normally do.
+ super(OrderedContainer, self).__setitem__(key, object)
+ if not foo:
+ self._order.append(key)
+
+ def __delitem__(self, key):
+ # First do whatever containers normally do.
+ super(OrderedContainer, self).__delitem__(key)
+ self._order.remove(key)
+
+ def updateOrder(self, order):
+ if set(order) != set(self._order):
+ raise ValueError("Incompatible key set.")
+
+ self._order = PersistentList()
+ self._order.extend(order)
+ notifyContainerModified(self)
+
+
+class Site(SiteManagerContainer):
+ pass
+
+ at component.adapter(Site, IObjectAddedEvent)
+def addSiteHandler(site, event):
+ sitemanager = LocalSiteManager(site)
+ # LocalSiteManager creates the 'default' folder in its __init__.
+ # It's not needed anymore in new versions of Zope 3, therefore we
+ # remove it
+ del sitemanager['default']
+ site.setSiteManager(sitemanager)
+
+
+class Application(Site):
+ """A top-level application object."""
+ interface.implements(interfaces.IApplication)
+
+
+class LocalUtility(Model):
+ pass
+
+
+class Annotation(persistent.Persistent):
+ pass
+
+
+class View(grokcore.view.View):
+ interface.implements(interfaces.IGrokView)
+
+ def application_url(self, name=None):
+ obj = self.context
+ while obj is not None:
+ if isinstance(obj, Application):
+ return self.url(obj, name)
+ obj = obj.__parent__
+ raise ValueError("No application found.")
+
+ def flash(self, message, type='message'):
+ source = component.getUtility(
+ z3c.flashmessage.interfaces.IMessageSource, name='session')
+ source.send(message, type)
+
+
+class Form(grokcore.formlib.Form, View):
+ interface.implements(interfaces.IGrokForm)
+
+
+class AddForm(grokcore.formlib.AddForm, View):
+ interface.implements(interfaces.IGrokForm)
+
+
+class DisplayForm(grokcore.formlib.DisplayForm, View):
+ interface.implements(interfaces.IGrokForm)
+
+
+class EditForm(grokcore.formlib.EditForm, View):
+ interface.implements(interfaces.IGrokForm)
+
+
+class XMLRPC(object):
+ pass
+
+class REST(zope.location.Location):
+ interface.implements(interfaces.IREST)
+
+ def __init__(self, context, request):
+ self.context = self.__parent__ = context
+ self.request = request
+ self.body = request.bodyStream.getCacheStream().read()
+
+ @property
+ def response(self):
+ return self.request.response
+
+## def GET(self):
+## raise GrokMethodNotAllowed(self.context, self.request)
+
+## def POST(self):
+## raise GrokMethodNotAllowed(self.context, self.request)
+
+## def PUT(self):
+## raise GrokMethodNotAllowed(self.context, self.request)
+
+## def DELETE(self):
+## raise GrokMethodNotAllowed(self.context, self.request)
+
+class JSON(BrowserPage):
+
+ def __call__(self):
+ view_name = self.__view_name__
+ method = getattr(self, view_name)
+ method_result = mapply(method, (), self.request)
+ return simplejson.dumps(method_result)
+
+
+class Traverser(object):
+ interface.implements(IBrowserPublisher)
+
+ def __init__(self, context, request):
+ self.context = context
+ self.request = request
+
+ def browserDefault(self, request):
+ # if we have a RESTful request, we will handle
+ # GET, POST and HEAD differently (PUT and DELETE are handled already
+ # but not on the BrowserRequest layer but the HTTPRequest layer)
+ if IRESTLayer.providedBy(request):
+ rest_view = component.getMultiAdapter(
+ (self.context, self.request),
+ name=request.method)
+ return rest_view, ()
+ view_name = getDefaultViewName(self.context, request)
+ view_uri = "@@%s" % view_name
+ return self.context, (view_uri,)
+
+ def publishTraverse(self, request, name):
+ subob = self.traverse(name)
+ if subob is not None:
+ return util.safely_locate_maybe(subob, self.context, name)
+
+ traversable_dict = grok.traversable.bind().get(self.context)
+ if traversable_dict:
+ if name in traversable_dict:
+ subob = getattr(self.context, traversable_dict[name])
+ if callable(subob):
+ subob = subob()
+ return util.safely_locate_maybe(subob, self.context, name)
+
+ # XXX Special logic here to deal with containers. It would be
+ # good if we wouldn't have to do this here. One solution is to
+ # rip this out and make you subclass ContainerTraverser if you
+ # wanted to override the traversal behaviour of containers.
+ if IReadContainer.providedBy(self.context):
+ item = self.context.get(name)
+ if item is not None:
+ return item
+
+ view = component.queryMultiAdapter((self.context, request), name=name)
+ if view is not None:
+ return view
+
+ raise NotFound(self.context, name, request)
+
+ def traverse(self, name):
+ # this will be overridden by subclasses
+ pass
+
+
+class ContextTraverser(Traverser):
+ component.adapts(interfaces.IContext, IHTTPRequest)
+
+ def traverse(self, name):
+ traverse = getattr(self.context, 'traverse', None)
+ if traverse:
+ return traverse(name)
+
+
+class ContainerTraverser(Traverser):
+ component.adapts(interfaces.IContainer, IHTTPRequest)
+
+ def traverse(self, name):
+ traverse = getattr(self.context, 'traverse', None)
+ if traverse:
+ result = traverse(name)
+ if result is not None:
+ return result
+ # try to get the item from the container
+ return self.context.get(name)
+
+
+class IndexesClass(object):
+ def __init__(self, name, bases=(), attrs=None):
+ if attrs is None:
+ return
+ indexes = {}
+ for name, value in attrs.items():
+ # Ignore everything that's not an index definition object
+ # except for values set by directives
+ if '.' in name:
+ setattr(self, name, value)
+ continue
+ if not interfaces.IIndexDefinition.providedBy(value):
+ continue
+ indexes[name] = value
+ self.__grok_indexes__ = indexes
+ # __grok_module__ is needed to make defined_locally() return True for
+ # inline templates
+ self.__grok_module__ = martian.util.caller_module()
+
+Indexes = IndexesClass('Indexes')
+
+
+class Role(Role):
+ pass
+
+class IRESTLayer(IBrowserRequest):
+ pass
+
+class RESTProtocol(object):
+ pass
+
+class ViewletManager(ViewletManagerBase):
+ interface.implements(interfaces.IViewletManager)
+
+ template = None
+
+ def __init__(self, context, request, view):
+ super(ViewletManager, self).__init__(context, request, view)
+ self.context = context
+ self.request = request
+ self.view = view
+ self.__name__ = self.__view_name__
+ self.static = component.queryAdapter(
+ self.request,
+ interface.Interface,
+ name=self.module_info.package_dotted_name
+ )
+
+ def sort(self, viewlets):
+ """Sort the viewlets.
+
+ ``viewlets`` is a list of tuples of the form (name, viewlet).
+ """
+ # In Grok, the default order of the viewlets is determined by
+ # util.sort_components. util.sort_components() however expects
+ # a list of just components, but sort() is supposed to deal
+ # with a list of (name, viewlet) tuples.
+ # To handle this situation we first store the name part on the
+ # viewlet, then use util.sort_components() and then "unpack"
+ # the name from the viewlet and recreate the list of (name,
+ # viewlet) tuples, now in the correct order.
+ s_viewlets = []
+ for name, viewlet in viewlets:
+ # Stuff away viewlet name so we can later retrieve it.
+ # XXX We loose name information in case the same viewlet
+ # is in the viewlets list twice, but with a different
+ # name. Most probably this situation doesn't occur.
+ viewlet.__viewlet_name__ = name
+ s_viewlets.append(viewlet)
+ s_viewlets = util.sort_components(s_viewlets)
+ return [(viewlet.__viewlet_name__, viewlet) for viewlet in s_viewlets]
+
+ def default_namespace(self):
+ namespace = {}
+ namespace['context'] = self.context
+ namespace['request'] = self.request
+ namespace['static'] = self.static
+ namespace['view'] = self.view
+ namespace['viewletmanager'] = self
+ return namespace
+
+ def namespace(self):
+ return {}
+
+ def render(self):
+ """See zope.contentprovider.interfaces.IContentProvider"""
+ # Now render the view
+ if self.template:
+ return self.template.render(self)
+ else:
+ return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
+
+
+class Viewlet(ViewletBase):
+ """Batteries included viewlet.
+ """
+
+ def __init__(self, context, request, view, manager):
+ super(Viewlet, self).__init__(context, request, view, manager)
+ self.context = context
+ self.request = request
+ self.view = view
+ self.viewletmanager = manager
+ self.__name__ = self.__view_name__
+ self.static = component.queryAdapter(
+ self.request,
+ interface.Interface,
+ name=self.module_info.package_dotted_name
+ )
+
+ def default_namespace(self):
+ namespace = {}
+ namespace['context'] = self.context
+ namespace['request'] = self.request
+ namespace['static'] = self.static
+ namespace['view'] = self.view
+ namespace['viewlet'] = self
+ namespace['viewletmanager'] = self.manager
+ return namespace
+
+ def namespace(self):
+ return {}
+
+ def update(self):
+ pass
+
+ def render(self):
+ return self.template.render(self)
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/configure.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/configure.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,84 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ xmlns:grok="http://namespaces.zope.org/grok">
+
+ <include package="zope.security" file="meta.zcml" />
+ <include package="zope.i18n" file="meta.zcml" />
+ <include package="zope.securitypolicy" file="meta.zcml" />
+ <include package="zope.app.zcmlfiles" file="meta.zcml" />
+ <include package="grok" file="meta.zcml" />
+
+ <include package="zope.annotation" />
+ <include package="zope.copypastemove" />
+ <include package="zope.contentprovider" />
+ <include package="zope.formlib" />
+ <include package="zope.i18n.locales" />
+ <include package="zope.publisher" />
+ <include package="zope.securitypolicy" />
+ <include package="zope.size" />
+ <include package="zope.traversing" />
+ <include package="zope.traversing.browser" />
+ <include package="zope.app.zcmlfiles" />
+ <include package="zope.app.authentication" />
+ <include package="zope.app.intid" />
+ <include package="zope.app.keyreference" />
+ <include package="zope.app.catalog" />
+ <include package="zope.app.renderer" />
+ <include package="zope.app.session" />
+
+ <include package="grokcore.view" />
+ <include package="grokcore.formlib" />
+
+ <securityPolicy
+ component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy" />
+
+ <adapter factory=".components.ContextTraverser" />
+ <adapter factory=".components.ContainerTraverser" />
+
+ <browser:defaultView
+ for=".interfaces.IContext"
+ name="index"
+ />
+
+ <subscriber handler=".components.addSiteHandler" />
+
+ <!-- we register a ++rest++ traversal namespace -->
+ <adapter
+ factory=".rest.rest_skin"
+ for="* zope.publisher.interfaces.browser.IHTTPRequest"
+ provides="zope.traversing.interfaces.ITraversable"
+ name="rest"
+ />
+
+ <!-- this overrides Zope 3's publication factories because they have
+ the same name; we also need to change the priority because of
+ the ZCML discriminator -->
+ <publisher
+ name="XMLRPC"
+ factory=".publication.GrokXMLRPCFactory"
+ methods="POST"
+ mimetypes="text/xml"
+ priority="21"
+ />
+
+ <publisher
+ name="BROWSER"
+ factory=".publication.GrokBrowserFactory"
+ methods="GET POST HEAD"
+ mimetypes="*"
+ priority="11"
+ />
+
+ <publisher
+ name="HTTP"
+ factory=".publication.GrokHTTPFactory"
+ methods="*"
+ mimetypes="*"
+ priority="1"
+ />
+
+ <!-- need to grok this for some basic REST support -->
+ <grok:grok package=".rest" />
+
+</configure>
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/directive.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/directive.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,143 @@
+##############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grok directives.
+"""
+
+import sys
+import grok
+from zope import interface
+from zope.interface.interfaces import IInterface
+from zope.interface.interface import TAGGED_DATA
+
+from zope.publisher.interfaces.browser import IBrowserView
+
+import martian
+from martian import util
+from martian.error import GrokImportError, GrokError
+from martian.directive import StoreOnce, StoreMultipleTimes
+from grokcore.component.scan import UnambiguousComponentScope
+from grok import components
+
+class local_utility(martian.Directive):
+ scope = martian.CLASS
+ store = martian.DICT
+
+ def factory(self, factory, provides=None, name=u'',
+ setup=None, public=False, name_in_container=None):
+ if provides is not None and not IInterface.providedBy(provides):
+ raise GrokImportError("You can only pass an interface to the "
+ "provides argument of %s." % self.name)
+
+ if provides is None:
+ provides = grok.provides.bind().get(factory)
+
+ if provides is None:
+ if util.check_subclass(factory, grok.LocalUtility):
+ baseInterfaces = interface.implementedBy(grok.LocalUtility)
+ utilityInterfaces = interface.implementedBy(factory)
+ provides = list(utilityInterfaces - baseInterfaces)
+
+ if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
+ raise GrokImportError(
+ "Cannot determine which interface to use "
+ "for utility registration of %r. "
+ "It implements an interface that is a specialization "
+ "of an interface implemented by grok.LocalUtility. "
+ "Specify the interface by either using grok.provides "
+ "on the utility or passing 'provides' to "
+ "grok.local_utility." % factory, factory)
+ else:
+ provides = list(interface.implementedBy(factory))
+
+ util.check_implements_one_from_list(provides, factory)
+ provides = provides[0]
+
+ if (provides, name) in self.frame.f_locals.get(self.dotted_name(), {}):
+ raise GrokImportError(
+ "Conflicting local utility registration %r. "
+ "Local utilities are registered multiple "
+ "times for interface %r and name %r." %
+ (factory, provides, name), factory)
+
+ info = LocalUtilityInfo(factory, provides, name, setup, public,
+ name_in_container)
+ return (provides, name), info
+
+
+class LocalUtilityInfo(object):
+
+ _order = 0
+
+ def __init__(self, factory, provides, name=u'',
+ setup=None, public=False, name_in_container=None):
+ self.factory = factory
+ self.provides = provides
+ self.name = name
+ self.setup = setup
+ self.public = public
+ self.name_in_container = name_in_container
+
+ self.order = LocalUtilityInfo._order
+ LocalUtilityInfo._order += 1
+
+ def __cmp__(self, other):
+ # LocalUtilityInfos have an inherit sort order by which the
+ # registrations take place.
+ return cmp(self.order, other.order)
+
+
+class site(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ validate = martian.validateInterfaceOrClass
+
+class permissions(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ default = []
+
+ def factory(*args):
+ return args
+
+class OneInterfaceOrClassOnClassOrModule(martian.Directive):
+ """Convenience base class. Not for public use."""
+ scope = martian.CLASS_OR_MODULE
+ store = martian.ONCE
+ validate = martian.validateInterfaceOrClass
+
+class viewletmanager(OneInterfaceOrClassOnClassOrModule):
+ scope = UnambiguousComponentScope('viewletmanager')
+
+class view(OneInterfaceOrClassOnClassOrModule):
+ default = IBrowserView
+
+class traversable(martian.Directive):
+ scope = martian.CLASS
+ store = martian.DICT
+
+ def factory(self, attr, name=None):
+ if name is None:
+ name = attr
+ return (name, attr)
+
+class order(martian.Directive):
+ scope = martian.CLASS
+ store = martian.ONCE
+ default = 0, 0
+
+ _order = 0
+
+ def factory(self, value=0):
+ order._order += 1
+ return value, order._order
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftesting.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftesting.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,35 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:grok="http://namespaces.zope.org/grok"
+ i18n_domain="grok"
+ package="grok"
+ >
+
+ <include package="grok" />
+ <grok:grok package="grok.ftests" />
+
+ <securityPolicy
+ component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+ />
+
+ <unauthenticatedPrincipal
+ id="zope.anybody"
+ title="Unauthenticated User"
+ />
+ <grant
+ permission="zope.View"
+ principal="zope.anybody"
+ />
+
+ <principal
+ id="zope.mgr"
+ title="Manager"
+ login="mgr"
+ password="mgrpw"
+ />
+
+ <role id="zope.Manager" title="Site Manager" />
+ <grantAll role="zope.Manager" />
+ <grant role="zope.Manager" principal="zope.mgr" />
+
+</configure>
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/ftests (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/ftests)
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/index.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/index.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,75 @@
+#############################################################################
+#
+# Copyright (c) 2007-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.
+#
+##############################################################################
+"""Grok index definitions
+"""
+import sys
+
+from zope.interface import implements
+from zope.interface.interfaces import IMethod, IInterface
+
+from zope.app.catalog.field import FieldIndex
+from zope.app.catalog.text import TextIndex
+from zc.catalog.catalogindex import SetIndex
+
+from martian.error import GrokError, GrokImportError
+from martian.util import frame_is_class
+
+from grok.interfaces import IIndexDefinition
+
+class IndexDefinition(object):
+ implements(IIndexDefinition)
+
+ index_class = None
+
+ def __init__(self, *args, **kw):
+ frame = sys._getframe(1)
+ if not frame_is_class(frame):
+ raise GrokImportError(
+ "%r can only be instantiated on class level." % self.__class__)
+ # store any extra parameters to pass to index later
+ self._args = args
+ self._attribute = kw.pop('attribute', None)
+ self._kw = kw
+
+ def setup(self, catalog, name, context, module_info):
+ if self._attribute is not None:
+ field_name = self._attribute
+ else:
+ field_name = name
+
+ if IInterface.providedBy(context):
+ try:
+ method = context[field_name]
+ except KeyError:
+ raise GrokError("grok.Indexes in %r refers to an attribute or "
+ "method %r on interface %r, but this does not "
+ "exist." % (module_info.getModule(),
+ field_name, context), None)
+ call = IMethod.providedBy(method)
+ else:
+ call = callable(getattr(context, field_name, None))
+ context = None # no interface lookup
+ catalog[name] = self.index_class(field_name=field_name,
+ interface=context,
+ field_callable=call,
+ *self._args, **self._kw)
+
+class Field(IndexDefinition):
+ index_class = FieldIndex
+
+class Text(IndexDefinition):
+ index_class = TextIndex
+
+class Set(IndexDefinition):
+ index_class = SetIndex
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/interfaces.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/interfaces.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,234 @@
+##############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grok interfaces
+"""
+from zope import interface, schema
+from zope.formlib.interfaces import reConstraint
+from zope.interface.interfaces import IInterface
+from zope.viewlet.interfaces import IViewletManager as IViewletManagerBase
+from zope.app.container.interfaces import IContainer as IContainerBase
+
+import grokcore.component.interfaces
+import grokcore.formlib.interfaces
+import grokcore.security.interfaces
+import grokcore.view.interfaces
+
+# Expose interfaces from grokcore.* packages as well:
+from grokcore.component.interfaces import IContext
+from grokcore.component.interfaces import IGrokErrors
+from grokcore.view.interfaces import ITemplateFileFactory
+from grokcore.view.interfaces import ITemplate
+
+
+class IGrokBaseClasses(grokcore.component.interfaces.IBaseClasses,
+ grokcore.security.interfaces.IBaseClasses,
+ grokcore.view.interfaces.IBaseClasses):
+ Model = interface.Attribute("Base class for persistent content objects "
+ "(models).")
+ Container = interface.Attribute("Base class for containers.")
+ OrderedContainer = interface.Attribute("Base class for ordered containers.")
+ Site = interface.Attribute("Mixin class for sites.")
+ Application = interface.Attribute("Base class for applications.")
+ Annotation = interface.Attribute("Base class for persistent annotations.")
+ LocalUtility = interface.Attribute("Base class for local utilities.")
+ XMLRPC = interface.Attribute("Base class for XML-RPC methods.")
+ JSON = interface.Attribute("Base class for JSON methods.")
+ REST = interface.Attribute("Base class for REST views.")
+ Traverser = interface.Attribute("Base class for custom traversers.")
+ Indexes = interface.Attribute("Base class for catalog index definitions.")
+ ViewletManager = interface.Attribute("Base class for viewletmanager.")
+ Viewlet = interface.Attribute("Base class for viewlet.")
+ Role = interface.Attribute("Base class for roles.")
+
+
+class IGrokDirectives(grokcore.component.interfaces.IDirectives,
+ grokcore.security.interfaces.IDirectives,
+ grokcore.view.interfaces.IDirectives):
+
+ def local_utility(factory, provides=None, name=u'',
+ setup=None, public=False, name_in_container=None):
+ """Register a local utility.
+
+ factory - the factory that creates the local utility
+ provides - the interface the utility should be looked up with
+ name - the name of the utility
+ setup - a callable that receives the utility as its single argument,
+ it is called after the utility has been created and stored
+ public - if False, the utility will be stored below ++etc++site
+ if True, the utility will be stored directly in the site.
+ The site should in this case be a container.
+ name_in_container - the name to use for storing the utility
+ """
+
+ def permissions(permissions):
+ """Specify the permissions that comprise a role.
+ """
+
+ def site(class_or_interface):
+ """Specifies the site that an indexes definition is for.
+
+ It can only be used inside grok.Indexes subclasses.
+ """
+
+ def order(value=None):
+ """Control the ordering of components.
+
+ If the value is specified, the order will be determined by sorting on
+ it.
+ If no value is specified, the order will be determined by definition
+ order within the module.
+ If the directive is absent, the order will be determined by class name.
+ (unfortunately our preferred default behavior on absence which would
+ be like grok.order() without argument is hard to implement in Python)
+
+ Inter-module order is by dotted name of the module the
+ components are in; unless an explicit argument is specified to
+ ``grok.order()``, components are grouped by module.
+
+ The function grok.util.sort_components can be used to sort
+ components according to these rules.
+ """
+
+
+class IGrokEvents(interface.Interface):
+
+ IObjectCreatedEvent = interface.Attribute("")
+
+ ObjectCreatedEvent = interface.Attribute("")
+
+ IObjectModifiedEvent = interface.Attribute("")
+
+ ObjectModifiedEvent = interface.Attribute("")
+
+ IObjectCopiedEvent = interface.Attribute("")
+
+ ObjectCopiedEvent = interface.Attribute("")
+
+ IObjectAddedEvent = interface.Attribute("")
+
+ ObjectAddedEvent = interface.Attribute("")
+
+ IObjectMovedEvent = interface.Attribute("")
+
+ ObjectMovedEvent = interface.Attribute("")
+
+ IObjectRemovedEvent = interface.Attribute("")
+
+ ObjectRemovedEvent = interface.Attribute("")
+
+ IContainerModifiedEvent = interface.Attribute("")
+
+ ContainerModifiedEvent = interface.Attribute("")
+
+
+class IGrokAPI(grokcore.security.interfaces.IGrokcoreSecurityAPI,
+ grokcore.view.interfaces.IGrokcoreViewAPI,
+ grokcore.formlib.interfaces.IGrokcoreFormlibAPI,
+ IGrokBaseClasses, IGrokDirectives,
+ IGrokEvents, IGrokErrors):
+
+ # BBB this is deprecated
+ def grok(dotted_name):
+ """Grok a module or package specified by ``dotted_name``.
+
+ NOTE: This function will be removed from the public Grok
+ public API. For tests and interpreter sessions, use
+ grok.testing.grok().
+ """
+
+ # BBB this is deprecated
+ def grok_component(name, component, context=None, module_info=None,
+ templates=None):
+ """Grok an arbitrary object. Can be useful during testing.
+
+ name - the name of the component (class name, or global instance name
+ as it would appear in a module).
+ component - the object (class, etc) to grok.
+ context - the context object (optional).
+ module_info - the module being grokked (optional).
+ templates - the templates registry (optional).
+
+ Note that context, module_info and templates might be required
+ for some grokkers which rely on them.
+
+ NOTE: This function will be removed from the public Grok
+ public API. For tests and interpreter sessions, use
+ grok.testing.grok_component().
+ """
+
+ def notify(event):
+ """Send ``event`` to event subscribers."""
+
+ def getSite():
+ """Get the current site."""
+
+
+ IRESTSkinType = interface.Attribute('The REST skin type')
+
+
+class IGrokView(grokcore.view.interfaces.IGrokView):
+ """Grok views all provide this interface."""
+
+ def application_url(name=None):
+ """Return the URL of the closest application object in the
+ hierarchy or the URL of a named object (``name`` parameter)
+ relative to the closest application object.
+ """
+
+ def flash(message, type='message'):
+ """Send a short message to the user."""
+
+
+class IGrokForm(grokcore.formlib.interfaces.IGrokForm, IGrokView):
+ """All Grok forms provides this interface."""
+
+
+class IREST(interface.Interface):
+ context = interface.Attribute("Object that the REST handler presents.")
+
+ request = interface.Attribute("Request that REST handler was looked"
+ "up with.")
+
+ body = interface.Attribute(
+ """The text of the request body.""")
+
+class IApplication(interface.Interface):
+ """Marker-interface for grok application factories.
+
+ Used to register applications as utilities to look them up and
+ provide a list of grokked applications.
+ """
+
+class IIndexDefinition(interface.Interface):
+ """Define an index for grok.Indexes.
+ """
+
+ def setup(catalog, name, context):
+ """Set up index called name in given catalog.
+
+ Use name for index name and attribute to index. Set up
+ index for interface or class context.
+ """
+
+class IRESTSkinType(IInterface):
+ """Skin type for REST requests.
+ """
+
+class IContainer(IContext, IContainerBase):
+ """A Grok container.
+ """
+
+class IViewletManager(IViewletManagerBase):
+ """The Grok viewlet manager.
+ """
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,537 @@
+#############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grokkers for the various components."""
+
+import zope.component.interface
+from zope import interface, component
+from zope.publisher.interfaces.browser import (IDefaultBrowserLayer,
+ IBrowserRequest,
+ IBrowserPublisher)
+from zope.publisher.interfaces.http import IHTTPRequest
+
+from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
+from zope.viewlet.interfaces import IViewletManager, IViewlet
+from zope.securitypolicy.interfaces import IRole
+from zope.securitypolicy.rolepermission import rolePermissionManager
+
+from zope.annotation.interfaces import IAnnotations
+
+from zope.app.publisher.xmlrpc import MethodPublisher
+from zope.app.container.interfaces import IContainer
+from zope.app.container.interfaces import INameChooser
+from zope.app.container.contained import contained
+
+from zope.app.intid import IntIds
+from zope.app.intid.interfaces import IIntIds
+from zope.app.catalog.catalog import Catalog
+from zope.app.catalog.interfaces import ICatalog
+
+from zope.exceptions.interfaces import DuplicationError
+
+import martian
+from martian.error import GrokError
+from martian import util
+
+import grok
+from grok import components
+from grok.util import make_checker
+from grok.interfaces import IRESTSkinType
+from grok.interfaces import IViewletManager as IGrokViewletManager
+
+from grokcore.component.scan import determine_module_component
+from grokcore.security.meta import PermissionGrokker
+
+from grokcore.view.meta.views import (
+ default_view_name, default_fallback_to_name)
+
+
+def default_annotation_provides(factory, module, **data):
+ base_interfaces = interface.implementedBy(grok.Annotation)
+ factory_interfaces = interface.implementedBy(factory)
+ real_interfaces = list(factory_interfaces - base_interfaces)
+ util.check_implements_one_from_list(real_interfaces, factory)
+ return real_interfaces[0]
+
+def default_annotation_name(factory, module, **data):
+ return factory.__module__ + '.' + factory.__name__
+
+
+class ViewletManagerContextGrokker(martian.GlobalGrokker):
+
+ martian.priority(1001)
+
+ def grok(self, name, module, module_info, config, **kw):
+ viewletmanager = determine_module_component(module_info,
+ grok.viewletmanager,
+ IGrokViewletManager)
+ grok.viewletmanager.set(module, viewletmanager)
+ return True
+
+
+class XMLRPCGrokker(martian.MethodGrokker):
+ martian.component(grok.XMLRPC)
+ martian.directive(grok.context)
+ martian.directive(grok.require, name='permission')
+
+ def execute(self, factory, method, config, context, permission, **kw):
+ name = method.__name__
+
+ # Make sure that the class inherits MethodPublisher, so that the
+ # views have a location
+ method_view = type(
+ factory.__name__, (factory, MethodPublisher),
+ {'__call__': method}
+ )
+
+ adapts = (context, IXMLRPCRequest)
+ config.action(
+ discriminator=('adapter', adapts, interface.Interface, name),
+ callable=component.provideAdapter,
+ args=(method_view, adapts, interface.Interface, name),
+ )
+ config.action(
+ discriminator=('protectName', method_view, '__call__'),
+ callable=make_checker,
+ args=(factory, method_view, permission),
+ )
+ return True
+
+
+class RESTGrokker(martian.MethodGrokker):
+ martian.component(grok.REST)
+ martian.directive(grok.context)
+ martian.directive(grok.layer, default=grok.IRESTLayer)
+ martian.directive(grok.require, name='permission')
+
+ def execute(self, factory, method, config, permission, context, layer, **kw):
+ name = method.__name__
+
+ method_view = type(
+ factory.__name__, (factory,),
+ {'__call__': method }
+ )
+
+ adapts = (context, layer)
+ config.action(
+ discriminator=('adapter', adapts, interface.Interface, name),
+ callable=component.provideAdapter,
+ args=(method_view, adapts, interface.Interface, name),
+ )
+ config.action(
+ discriminator=('protectName', method_view, '__call__'),
+ callable=make_checker,
+ args=(factory, method_view, permission),
+ )
+ return True
+
+
+class JSONGrokker(martian.MethodGrokker):
+ martian.component(grok.JSON)
+ martian.directive(grok.context)
+ martian.directive(grok.require, name='permission')
+
+ # TODO: this grokker doesn't support layers yet
+
+ def execute(self, factory, method, config, context, permission, **kw):
+ # Create a new class with a __view_name__ attribute so the
+ # JSON class knows what method to call.
+ method_view = type(
+ factory.__name__, (factory,),
+ {'__view_name__': method.__name__}
+ )
+ adapts = (context, IDefaultBrowserLayer)
+ name = method.__name__
+
+ config.action(
+ discriminator=('adapter', adapts, interface.Interface, name),
+ callable=component.provideAdapter,
+ args=(method_view, adapts, interface.Interface, name),
+ )
+ config.action(
+ discriminator=('protectName', method_view, '__call__'),
+ callable=make_checker,
+ args=(factory, method_view, permission),
+ )
+ return True
+
+
+class TraverserGrokker(martian.ClassGrokker):
+ martian.component(grok.Traverser)
+ martian.directive(grok.context)
+
+ def execute(self, factory, config, context, **kw):
+ adapts = (context, IHTTPRequest)
+ config.action(
+ discriminator=('adapter', adapts, IBrowserPublisher, ''),
+ callable=component.provideAdapter,
+ args=(factory, adapts, IBrowserPublisher),
+ )
+ return True
+
+
+class SiteGrokker(martian.ClassGrokker):
+ martian.component(grok.Site)
+ martian.priority(500)
+ martian.directive(grok.local_utility, name='infos')
+
+ def execute(self, factory, config, infos, **kw):
+ if not infos:
+ return False
+
+ infos = infos.values()
+ for info in infos:
+ if info.public and not IContainer.implementedBy(factory):
+ raise GrokError(
+ "Cannot set public to True with grok.local_utility as "
+ "the site (%r) is not a container." %
+ factory, factory)
+
+ # Store the list of info objects in their "natural" order on the
+ # site class. They will be picked up by a subscriber doing the
+ # actual registrations in definition order.
+ factory.__grok_utilities_to_install__ = sorted(infos)
+ adapts = (factory, grok.IObjectAddedEvent)
+
+ config.action(
+ discriminator=None,
+ callable=component.provideHandler,
+ args=(localUtilityRegistrationSubscriber, adapts),
+ )
+ return True
+
+
+def localUtilityRegistrationSubscriber(site, event):
+ """A subscriber that fires to set up local utilities.
+ """
+ installed = getattr(site, '__grok_utilities_installed__', False)
+ if installed:
+ return
+
+ for info in getattr(site.__class__, '__grok_utilities_to_install__', []):
+ setupUtility(site, info.factory(), info.provides, name=info.name,
+ name_in_container=info.name_in_container,
+ public=info.public, setup=info.setup)
+
+ # we are done. If this subscriber gets fired again, we therefore
+ # do not register utilities anymore
+ site.__grok_utilities_installed__ = True
+
+
+def setupUtility(site, utility, provides, name=u'',
+ name_in_container=None, public=False, setup=None):
+ """Set up a utility in a site.
+
+ site - the site to set up the utility in
+ utility - the utility to set up
+ provides - the interface the utility should be registered with
+ name - the name the utility should be registered under, default
+ the empty string (no name)
+ name_in_container - if given it will be used to add the utility
+ object to its container. Otherwise a name will be made up
+ public - if False, the utility will be stored in the site manager. If
+ True, the utility will be storedin the site (it is assumed the
+ site is a container)
+ setup - if not None, it will be called with the utility as its first
+ argument. This function can then be used to further set up the
+ utility.
+ """
+ site_manager = site.getSiteManager()
+
+ if not public:
+ container = site_manager
+ else:
+ container = site
+
+ if name_in_container is None:
+ name_in_container = INameChooser(container).chooseName(
+ utility.__class__.__name__, utility)
+ container[name_in_container] = utility
+
+ if setup is not None:
+ setup(utility)
+
+ site_manager.registerUtility(utility, provided=provides,
+ name=name)
+
+
+class RoleGrokker(martian.ClassGrokker):
+ martian.component(grok.Role)
+ martian.priority(martian.priority.bind().get(PermissionGrokker()) - 1)
+ martian.directive(grok.name)
+ martian.directive(grok.title, get_default=default_fallback_to_name)
+ martian.directive(grok.description)
+ martian.directive(grok.permissions)
+
+ def execute(self, factory, config, name, title, description,
+ permissions, **kw):
+ if not name:
+ raise GrokError(
+ "A role needs to have a dotted name for its id. Use "
+ "grok.name to specify one.", factory)
+ # We can safely convert to unicode, since the directives makes sure
+ # it is either unicode already or ASCII.
+ role = factory(unicode(name), unicode(title), unicode(description))
+
+ config.action(
+ discriminator=('utility', IRole, name),
+ callable=component.provideUtility,
+ args=(role, IRole, name),
+ )
+
+ for permission in permissions:
+ config.action(
+ discriminator=('grantPermissionToRole', permission, name),
+ callable=rolePermissionManager.grantPermissionToRole,
+ args=(permission, name),
+ )
+ return True
+
+
+class AnnotationGrokker(martian.ClassGrokker):
+ martian.component(grok.Annotation)
+ martian.directive(grok.context, name='adapter_context')
+ martian.directive(grok.provides, get_default=default_annotation_provides)
+ martian.directive(grok.name, get_default=default_annotation_name)
+
+ def execute(self, factory, config, adapter_context, provides, name, **kw):
+ @component.adapter(adapter_context)
+ @interface.implementer(provides)
+ def getAnnotation(context):
+ annotations = IAnnotations(context)
+ try:
+ result = annotations[name]
+ except KeyError:
+ result = factory()
+ annotations[name] = result
+
+ # Containment has to be set up late to allow containment
+ # proxies to be applied, if needed. This does not trigger
+ # an event and is idempotent if containment is set up
+ # already.
+ contained_result = contained(result, context, name)
+ return contained_result
+
+ config.action(
+ discriminator=('adapter', adapter_context, provides, ''),
+ callable=component.provideAdapter,
+ args=(getAnnotation,),
+ )
+ return True
+
+
+class ApplicationGrokker(martian.ClassGrokker):
+ martian.component(grok.Application)
+ martian.priority(500)
+
+ def grok(self, name, factory, module_info, config, **kw):
+ # XXX fail loudly if the same application name is used twice.
+ provides = grok.interfaces.IApplication
+ name = '%s.%s' % (module_info.dotted_name, name)
+ config.action(
+ discriminator=('utility', provides, name),
+ callable=component.provideUtility,
+ args=(factory, provides, name),
+ )
+ return True
+
+
+class IndexesGrokker(martian.InstanceGrokker):
+ martian.component(components.IndexesClass)
+
+ def grok(self, name, factory, module_info, config, **kw):
+ site = grok.site.bind().get(factory)
+ context = grok.context.bind().get(factory, module_info.getModule())
+ catalog_name = grok.name.bind().get(factory)
+
+ if site is None:
+ raise GrokError("No site specified for grok.Indexes "
+ "subclass in module %r. "
+ "Use grok.site() to specify."
+ % module_info.getModule(),
+ factory)
+ indexes = getattr(factory, '__grok_indexes__', None)
+ if indexes is None:
+ return False
+
+ subscriber = IndexesSetupSubscriber(catalog_name, indexes,
+ context, module_info)
+ subscribed = (site, grok.IObjectAddedEvent)
+ config.action(
+ discriminator=None,
+ callable=component.provideHandler,
+ args=(subscriber, subscribed),
+ )
+ return True
+
+
+class IndexesSetupSubscriber(object):
+
+ def __init__(self, catalog_name, indexes, context, module_info):
+ self.catalog_name = catalog_name
+ self.indexes = indexes
+ self.context = context
+ self.module_info = module_info
+
+ def __call__(self, site, event):
+ # make sure we have an intids
+ self._createIntIds(site)
+ # get the catalog
+ catalog = self._createCatalog(site)
+ # now install indexes
+ for name, index in self.indexes.items():
+ try:
+ index.setup(catalog, name, self.context, self.module_info)
+ except DuplicationError:
+ raise GrokError(
+ "grok.Indexes in module %r causes "
+ "creation of catalog index %r in catalog %r, "
+ "but an index with that name is already present." %
+ (self.module_info.getModule(), name, self.catalog_name),
+ None)
+
+ def _createCatalog(self, site):
+ """Create the catalog if needed and return it.
+
+ If the catalog already exists, return that.
+
+ """
+ catalog = zope.component.queryUtility(
+ ICatalog, name=self.catalog_name, context=site, default=None)
+ if catalog is not None:
+ return catalog
+ catalog = Catalog()
+ setupUtility(site, catalog, ICatalog, name=self.catalog_name)
+ return catalog
+
+ def _createIntIds(self, site):
+ """Create intids if needed, and return it.
+ """
+ intids = zope.component.queryUtility(
+ IIntIds, context=site, default=None)
+ if intids is not None:
+ return intids
+ intids = IntIds()
+ setupUtility(site, intids, IIntIds)
+ return intids
+
+
+class RESTProtocolGrokker(martian.ClassGrokker):
+ martian.component(grok.RESTProtocol)
+ martian.directive(grok.layer, default=IBrowserRequest)
+ martian.directive(grok.name, get_default=default_view_name)
+
+ def execute(self, factory, config, name, layer, **kw):
+ config.action(
+ discriminator=('restprotocol', name),
+ callable=zope.component.interface.provideInterface,
+ args=(name, layer, IRESTSkinType)
+ )
+ return True
+
+class ViewletManagerGrokker(martian.ClassGrokker):
+ martian.component(grok.ViewletManager)
+ martian.directive(grok.context)
+ martian.directive(grok.layer, default=IDefaultBrowserLayer)
+ martian.directive(grok.view)
+ martian.directive(grok.name)
+
+ def grok(self, name, factory, module_info, **kw):
+ # Need to store the module info object on the view class so that it
+ # can look up the 'static' resource directory.
+ factory.module_info = module_info
+ return super(ViewletManagerGrokker, self).grok(
+ name, factory, module_info, **kw)
+
+ def execute(self, factory, config, context, layer, view, name, **kw):
+ # This will be used to support __name__ on the viewlet manager
+ factory.__view_name__ = name
+
+ # find templates
+ templates = factory.module_info.getAnnotation('grok.templates', None)
+ if templates is not None:
+ config.action(
+ discriminator=None,
+ callable=self.checkTemplates,
+ args=(templates, factory.module_info, factory)
+ )
+
+ config.action(
+ discriminator = ('viewletManager', context, layer, view, name),
+ callable = component.provideAdapter,
+ args = (factory, (context, layer, view), IViewletManager, name)
+ )
+ return True
+
+ def checkTemplates(self, templates, module_info, factory):
+ def has_render(factory):
+ return factory.render != grok.components.ViewletManager.render
+ def has_no_render(factory):
+ # always has a render method
+ return False
+ templates.checkTemplates(module_info, factory, 'viewlet manager',
+ has_render, has_no_render)
+
+class ViewletGrokker(martian.ClassGrokker):
+ martian.component(grok.Viewlet)
+ martian.directive(grok.context)
+ martian.directive(grok.layer, default=IDefaultBrowserLayer)
+ martian.directive(grok.view)
+ martian.directive(grok.viewletmanager)
+ martian.directive(grok.name, get_default=default_view_name)
+ martian.directive(grok.require, name='permission')
+
+ def grok(self, name, factory, module_info, **kw):
+ # Need to store the module info object on the view class so that it
+ # can look up the 'static' resource directory.
+ factory.module_info = module_info
+ return super(ViewletGrokker, self).grok(
+ name, factory, module_info, **kw)
+
+ def execute(self, factory, config,
+ context, layer, view, viewletmanager, name, permission, **kw):
+ # This will be used to support __name__ on the viewlet
+ factory.__view_name__ = name
+
+ # find templates
+ templates = factory.module_info.getAnnotation('grok.templates', None)
+ if templates is not None:
+ config.action(
+ discriminator=None,
+ callable=self.checkTemplates,
+ args=(templates, factory.module_info, factory)
+ )
+
+ config.action(
+ discriminator = ('viewlet', context, layer,
+ view, viewletmanager, name),
+ callable = component.provideAdapter,
+ args = (factory, (context, layer, view, viewletmanager),
+ IViewlet, name)
+ )
+
+ config.action(
+ discriminator=('protectName', factory, '__call__'),
+ callable=make_checker,
+ args=(factory, factory, permission, ['update', 'render']),
+ )
+
+ return True
+
+ def checkTemplates(self, templates, module_info, factory):
+ def has_render(factory):
+ return factory.render != grok.components.Viewlet.render
+ def has_no_render(factory):
+ return not has_render(factory)
+ templates.checkTemplates(module_info, factory, 'viewlet',
+ has_render, has_no_render)
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/meta.zcml)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/meta.zcml 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,15 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:meta="http://namespaces.zope.org/meta"
+ xmlns:grok="http://namespaces.zope.org/grok">
+
+ <include package="z3c.autoinclude" file="meta.zcml" />
+
+ <!-- Load the grokkers -->
+ <include package="grokcore.component" file="meta.zcml" />
+ <include package="grokcore.formlib" file="meta.zcml" />
+ <include package="grokcore.security" file="meta.zcml" />
+ <include package="grokcore.view" file="meta.zcml" />
+ <grok:grok package=".meta" />
+
+</configure>
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/publication.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/publication.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,90 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok publication objects
+"""
+
+from grok.rest import GrokMethodNotAllowed
+
+from zope import component
+from zope.security.proxy import removeSecurityProxy
+from zope.security.checker import selectChecker
+from zope.publisher.publish import mapply
+
+from zope.app.publication.http import BaseHTTPPublication, HTTPPublication
+from zope.app.publication.browser import BrowserPublication
+from zope.app.publication.requestpublicationfactories import \
+ BrowserFactory, XMLRPCFactory, HTTPFactory
+from zope.app.http.interfaces import IHTTPException
+
+class ZopePublicationSansProxy(object):
+
+ def getApplication(self, request):
+ result = super(ZopePublicationSansProxy, self).getApplication(request)
+ return removeSecurityProxy(result)
+
+ def traverseName(self, request, ob, name):
+ result = super(ZopePublicationSansProxy, self).traverseName(
+ request, ob, name)
+ return removeSecurityProxy(result)
+
+ def callObject(self, request, ob):
+ checker = selectChecker(ob)
+ if checker is not None:
+ checker.check(ob, '__call__')
+ return super(ZopePublicationSansProxy, self).callObject(request, ob)
+
+
+class GrokBrowserPublication(ZopePublicationSansProxy, BrowserPublication):
+
+ def getDefaultTraversal(self, request, ob):
+ obj, path = super(GrokBrowserPublication, self).getDefaultTraversal(
+ request, ob)
+ return removeSecurityProxy(obj), path
+
+
+class GrokBrowserFactory(BrowserFactory):
+
+ def __call__(self):
+ request, publication = super(GrokBrowserFactory, self).__call__()
+ return request, GrokBrowserPublication
+
+
+class GrokXMLRPCPublication(ZopePublicationSansProxy, BaseHTTPPublication):
+ pass
+
+class GrokXMLRPCFactory(XMLRPCFactory):
+
+ def __call__(self):
+ request, publication = super(GrokXMLRPCFactory, self).__call__()
+ return request, GrokXMLRPCPublication
+
+
+class GrokHTTPPublication(ZopePublicationSansProxy, HTTPPublication):
+ def callObject(self, request, ob):
+ orig = ob
+ if not IHTTPException.providedBy(ob):
+ ob = component.queryMultiAdapter((ob, request),
+ name=request.method)
+ checker = selectChecker(ob)
+ if checker is not None:
+ checker.check(ob, '__call__')
+ ob = getattr(ob, request.method, None)
+ if ob is None:
+ raise GrokMethodNotAllowed(orig, request)
+ return mapply(ob, request.getPositionalArguments(), request)
+
+class GrokHTTPFactory(HTTPFactory):
+ def __call__(self):
+ request, publication = super(GrokHTTPFactory, self).__call__()
+ return request, GrokHTTPPublication
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/rest.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/rest.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,86 @@
+import grok
+
+from zope import component
+from zope.component.interfaces import ComponentLookupError
+
+from zope.traversing.interfaces import TraversalError
+from zope.traversing.namespace import view
+from zope.interface import Interface
+from zope.interface.interfaces import IInterface
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.publisher.interfaces.http import IHTTPRequest
+from zope.app.publication.http import MethodNotAllowed
+
+from grok.interfaces import IRESTSkinType
+from zope.publisher.browser import applySkin
+
+class GrokMethodNotAllowed(MethodNotAllowed):
+ pass
+
+class MethodNotAllowedView(grok.MultiAdapter):
+ grok.adapts(GrokMethodNotAllowed, IHTTPRequest)
+ grok.name('index.html')
+ grok.implements(Interface)
+
+ def __init__(self, error, request):
+ self.error = error
+ self.request = request
+ self.allow = self._getAllow()
+
+ def _getAllow(self):
+ allow = []
+ for method in ['GET', 'PUT', 'POST', 'DELETE']:
+ view = component.queryMultiAdapter(
+ (self.error.object, self.error.request),
+ name=method)
+ if view is not None:
+ is_not_allowed = getattr(view, 'is_not_allowed', False)
+ if not is_not_allowed:
+ allow.append(method)
+ allow.sort()
+ return allow
+
+ def __call__(self):
+ self.request.response.setHeader('Allow', ', '.join(self.allow))
+ self.request.response.setStatus(405)
+ return 'Method Not Allowed'
+
+class rest_skin(view):
+ """A rest skin.
+
+ This used to be supported by zope.traversing but the change was backed out.
+ We need it for our REST support.
+ """
+ def traverse(self, name, ignored):
+ self.request.shiftNameToApplication()
+ try:
+ skin = component.getUtility(IRESTSkinType, name)
+ except ComponentLookupError:
+ raise TraversalError("++rest++%s" % name)
+ applySkin(self.request, skin)
+ return self.context
+
+
+class NotAllowedREST(grok.REST):
+ """These are registered for everything by default to cause the correct
+ errors.
+
+ Any more specific REST view overrides this.
+ """
+ grok.layer(grok.IRESTLayer)
+ grok.context(Interface)
+
+ is_not_allowed = True
+
+ def GET(self):
+ raise GrokMethodNotAllowed(self.context, self.request)
+
+ def POST(self):
+ raise GrokMethodNotAllowed(self.context, self.request)
+
+ def PUT(self):
+ raise GrokMethodNotAllowed(self.context, self.request)
+
+ def DELETE(self):
+ raise GrokMethodNotAllowed(self.context, self.request)
+
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/testing.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,81 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Grok test helpers
+"""
+import sys
+import os.path
+import z3c.testsetup
+from zope.configuration.config import ConfigurationMachine
+from grokcore.component import zcml
+# Provide this import here for BBB reasons:
+from grokcore.component.testing import grok_component
+
+class GrokTestCollector(z3c.testsetup.TestCollector):
+
+ def initialize(self):
+ # inject the grok ftesting ZCML as fallback...
+ if 'zcml_config' in self.settings.keys():
+ return
+ pkg_path = os.path.dirname(self.package.__file__)
+ if os.path.isfile(os.path.join(pkg_path, 'ftesting.zcml')):
+ return
+ self.settings['zcml_config'] = os.path.join(
+ os.path.dirname(__file__), 'ftesting.zcml')
+ if 'layer_name' in self.settings.keys():
+ return
+ self.settings['layer_name'] = 'GrokFunctionalLayer'
+
+def register_all_tests(pkg, *args, **kw):
+ return GrokTestCollector(pkg, *args, **kw)
+
+def grok(module_name):
+ config = ConfigurationMachine()
+ zcml.do_grok('grokcore.component.meta', config)
+ zcml.do_grok('grokcore.security.meta', config)
+ zcml.do_grok('grokcore.view.meta', config)
+ zcml.do_grok('grokcore.view.templatereg', config)
+ zcml.do_grok('grokcore.formlib.meta', config)
+ zcml.do_grok('grok.meta', config)
+ zcml.do_grok(module_name, config)
+ config.execute_actions()
+
+def warn(message, category=None, stacklevel=1):
+ """Intended to replace warnings.warn in tests.
+
+ Modified copy from zope.deprecation.tests to:
+
+ * make the signature identical to warnings.warn
+ * to check for *.pyc and *.pyo files.
+
+ When zope.deprecation is fixed, this warn function can be removed again.
+ """
+ print "From grok.testing's warn():"
+
+ frame = sys._getframe(stacklevel)
+ path = frame.f_globals['__file__']
+ if path.endswith('.pyc') or path.endswith('.pyo'):
+ path = path[:-1]
+
+ file = open(path)
+ lineno = frame.f_lineno
+ for i in range(lineno):
+ line = file.readline()
+
+ print "%s:%s: %s: %s\n %s" % (
+ path,
+ frame.f_lineno,
+ category.__name__,
+ message,
+ line.strip(),
+ )
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/tests (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/tests)
Copied: Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py (from rev 92327, Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py)
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py (rev 0)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/site/util.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -0,0 +1,70 @@
+##############################################################################
+#
+# Copyright (c) 2006-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.
+#
+##############################################################################
+"""Grok utility functions.
+"""
+import grok
+import zope.location.location
+from zope import interface
+from zope.security.checker import NamesChecker, defineChecker
+
+from grokcore.security.util import check_permission
+
+def make_checker(factory, view_factory, permission, method_names=None):
+ """Make a checker for a view_factory associated with factory.
+
+ These could be one and the same for normal views, or different
+ in case we make method-based views such as for JSON and XMLRPC.
+ """
+ if method_names is None:
+ method_names = ['__call__']
+ if permission is not None:
+ check_permission(factory, permission)
+ if permission is None or permission == 'zope.Public':
+ checker = NamesChecker(method_names)
+ else:
+ checker = NamesChecker(method_names, permission)
+ defineChecker(view_factory, checker)
+
+def safely_locate_maybe(obj, parent, name):
+ """Set an object's __parent__ (and __name__) if the object's
+ __parent__ attribute doesn't exist yet or is None.
+
+ If the object provides ILocation, __parent__ and __name__ will be
+ set directly. A location proxy will be returned otherwise.
+ """
+ if getattr(obj, '__parent__', None) is not None:
+ return obj
+ # This either sets __parent__ or wraps 'obj' in a LocationProxy
+ return zope.location.location.located(obj, parent, name)
+
+def applySkin(request, skin, skin_type):
+ """Change the presentation skin for this request.
+ """
+ # Remove all existing skin declarations (commonly the default skin).
+ ifaces = [iface for iface in interface.directlyProvidedBy(request)
+ if not skin_type.providedBy(iface)]
+ # Add the new skin.
+ ifaces.append(skin)
+ interface.directlyProvides(request, *ifaces)
+
+def _sort_key(component):
+ # If components have a grok.order directive, sort by that.
+ explicit_order, implicit_order = grok.order.bind().get(component)
+ return (explicit_order,
+ component.__module__,
+ implicit_order,
+ component.__class__.__name__)
+
+def sort_components(components):
+ return sorted(components, key=_sort_key)
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/testing.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,81 +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.
-#
-##############################################################################
-"""Grok test helpers
-"""
-import sys
-import os.path
-import z3c.testsetup
-from zope.configuration.config import ConfigurationMachine
-from grokcore.component import zcml
-# Provide this import here for BBB reasons:
-from grokcore.component.testing import grok_component
-
-class GrokTestCollector(z3c.testsetup.TestCollector):
-
- def initialize(self):
- # inject the grok ftesting ZCML as fallback...
- if 'zcml_config' in self.settings.keys():
- return
- pkg_path = os.path.dirname(self.package.__file__)
- if os.path.isfile(os.path.join(pkg_path, 'ftesting.zcml')):
- return
- self.settings['zcml_config'] = os.path.join(
- os.path.dirname(__file__), 'ftesting.zcml')
- if 'layer_name' in self.settings.keys():
- return
- self.settings['layer_name'] = 'GrokFunctionalLayer'
-
-def register_all_tests(pkg, *args, **kw):
- return GrokTestCollector(pkg, *args, **kw)
-
-def grok(module_name):
- config = ConfigurationMachine()
- zcml.do_grok('grokcore.component.meta', config)
- zcml.do_grok('grokcore.security.meta', config)
- zcml.do_grok('grokcore.view.meta', config)
- zcml.do_grok('grokcore.view.templatereg', config)
- zcml.do_grok('grokcore.formlib.meta', config)
- zcml.do_grok('grok.meta', config)
- zcml.do_grok(module_name, config)
- config.execute_actions()
-
-def warn(message, category=None, stacklevel=1):
- """Intended to replace warnings.warn in tests.
-
- Modified copy from zope.deprecation.tests to:
-
- * make the signature identical to warnings.warn
- * to check for *.pyc and *.pyo files.
-
- When zope.deprecation is fixed, this warn function can be removed again.
- """
- print "From grok.testing's warn():"
-
- frame = sys._getframe(stacklevel)
- path = frame.f_globals['__file__']
- if path.endswith('.pyc') or path.endswith('.pyo'):
- path = path[:-1]
-
- file = open(path)
- lineno = frame.f_lineno
- for i in range(lineno):
- line = file.readline()
-
- print "%s:%s: %s: %s\n %s" % (
- path,
- frame.f_lineno,
- category.__name__,
- message,
- line.strip(),
- )
Deleted: Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py
===================================================================
--- Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py 2008-10-17 17:00:48 UTC (rev 92327)
+++ Sandbox/faassen/grokcore.site/trunk/src/grokcore/util.py 2008-10-17 17:02:25 UTC (rev 92328)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-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.
-#
-##############################################################################
-"""Grok utility functions.
-"""
-import grok
-import zope.location.location
-from zope import interface
-from zope.security.checker import NamesChecker, defineChecker
-
-from grokcore.security.util import check_permission
-
-def make_checker(factory, view_factory, permission, method_names=None):
- """Make a checker for a view_factory associated with factory.
-
- These could be one and the same for normal views, or different
- in case we make method-based views such as for JSON and XMLRPC.
- """
- if method_names is None:
- method_names = ['__call__']
- if permission is not None:
- check_permission(factory, permission)
- if permission is None or permission == 'zope.Public':
- checker = NamesChecker(method_names)
- else:
- checker = NamesChecker(method_names, permission)
- defineChecker(view_factory, checker)
-
-def safely_locate_maybe(obj, parent, name):
- """Set an object's __parent__ (and __name__) if the object's
- __parent__ attribute doesn't exist yet or is None.
-
- If the object provides ILocation, __parent__ and __name__ will be
- set directly. A location proxy will be returned otherwise.
- """
- if getattr(obj, '__parent__', None) is not None:
- return obj
- # This either sets __parent__ or wraps 'obj' in a LocationProxy
- return zope.location.location.located(obj, parent, name)
-
-def applySkin(request, skin, skin_type):
- """Change the presentation skin for this request.
- """
- # Remove all existing skin declarations (commonly the default skin).
- ifaces = [iface for iface in interface.directlyProvidedBy(request)
- if not skin_type.providedBy(iface)]
- # Add the new skin.
- ifaces.append(skin)
- interface.directlyProvides(request, *ifaces)
-
-def _sort_key(component):
- # If components have a grok.order directive, sort by that.
- explicit_order, implicit_order = grok.order.bind().get(component)
- return (explicit_order,
- component.__module__,
- implicit_order,
- component.__class__.__name__)
-
-def sort_components(components):
- return sorted(components, key=_sort_key)
More information about the Checkins
mailing list