[Checkins] SVN: grok/branches/faassen-index/src/grok/ A first
implementation of grok.Indexes, a way to make it
Martijn Faassen
faassen at infrae.com
Tue Apr 17 13:29:01 EDT 2007
Log message for revision 74204:
A first implementation of grok.Indexes, a way to make it
easier to set up catalog indexes.
Changed:
U grok/branches/faassen-index/src/grok/__init__.py
U grok/branches/faassen-index/src/grok/components.py
U grok/branches/faassen-index/src/grok/interfaces.py
U grok/branches/faassen-index/src/grok/meta.py
-=-
Modified: grok/branches/faassen-index/src/grok/__init__.py
===================================================================
--- grok/branches/faassen-index/src/grok/__init__.py 2007-04-17 17:27:25 UTC (rev 74203)
+++ grok/branches/faassen-index/src/grok/__init__.py 2007-04-17 17:29:01 UTC (rev 74204)
@@ -34,6 +34,7 @@
from grok.components import PageTemplate, PageTemplateFile, Container, Traverser
from grok.components import Site, GlobalUtility, LocalUtility, Annotation
from grok.components import Application, Form, AddForm, EditForm, DisplayForm
+from grok.components import Indexes
from grok.directive import (context, name, template, templatedir, provides,
baseclass, global_utility, local_utility,
define_permission, require)
Modified: grok/branches/faassen-index/src/grok/components.py
===================================================================
--- grok/branches/faassen-index/src/grok/components.py 2007-04-17 17:27:25 UTC (rev 74203)
+++ grok/branches/faassen-index/src/grok/components.py 2007-04-17 17:29:01 UTC (rev 74204)
@@ -115,8 +115,8 @@
class Application(Site):
"""A top-level application object."""
+ interface.implements(interfaces.IApplication)
-
class Adapter(object):
def __init__(self, context):
@@ -447,3 +447,24 @@
interface.implementsOnly(interfaces.IGrokForm)
template = default_display_template
+
+class IndexesClass(object):
+ def __init__(self, name, bases=(), attrs=None):
+ if attrs is None:
+ return
+ # make sure we take over __grok_context__
+ context = attrs.get('__grok_context__')
+ if context is not None:
+ self.__grok_context__ = context
+
+ indexes = {}
+ for name, value in attrs.items():
+ 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__ = util.caller_module()
+
+Indexes = IndexesClass('Indexes')
Modified: grok/branches/faassen-index/src/grok/interfaces.py
===================================================================
--- grok/branches/faassen-index/src/grok/interfaces.py 2007-04-17 17:27:25 UTC (rev 74203)
+++ grok/branches/faassen-index/src/grok/interfaces.py 2007-04-17 17:29:01 UTC (rev 74204)
@@ -365,3 +365,16 @@
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.
+ """
+
+
Modified: grok/branches/faassen-index/src/grok/meta.py
===================================================================
--- grok/branches/faassen-index/src/grok/meta.py 2007-04-17 17:27:25 UTC (rev 74203)
+++ grok/branches/faassen-index/src/grok/meta.py 2007-04-17 17:29:01 UTC (rev 74204)
@@ -15,6 +15,11 @@
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
+
import grok
from grok import util, components, formlib
from grok.error import GrokError
@@ -377,34 +382,51 @@
for info in util.class_annotation(site.__class__,
'grok.utilities_to_install', []):
- utility = info.factory()
- site_manager = site.getSiteManager()
+ setupUtility(site, info.factory(), info.provides, name=info.name,
+ name_in_container=info.name_in_container,
+ public=info.public, setup=info.setup)
- # store utility
- if not info.public:
- container = site_manager
- else:
- container = site
+ # we are done. If this subscriber gets fired again, we therefore
+ # do not register utilities anymore
+ site.__grok_utilities_installed__ = True
- name_in_container = info.name_in_container
- if name_in_container is None:
- name_in_container = INameChooser(container).chooseName(
- info.factory.__name__, utility)
- container[name_in_container] = utility
- # execute setup callback
- if info.setup is not None:
- info.setup(utility)
+def setupUtility(site, utility, provides, name=u'',
+ name_in_container=None, public=False, setup=None):
+ """Set up a utility in a site.
- # register utility
- site_manager.registerUtility(utility, provided=info.provides,
- name=info.name)
+ 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()
- # we are done. If this subscriber gets fired again, we therefore
- # do not register utilities anymore
- site.__grok_utilities_installed__ = True
+ 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 DefinePermissionGrokker(grok.ModuleGrokker):
priority = 1500
@@ -470,3 +492,55 @@
provides=grok.interfaces.IApplication,
name='%s.%s' % (module_info.dotted_name,
name))
+class IndexesGrokker(grok.InstanceGrokker):
+ component_class = components.IndexesClass
+
+ def register(self, context, name, factory, module_info, templates):
+ indexes = util.class_annotation(factory, 'grok.indexes', None)
+ if indexes is None:
+ return
+ context = util.determine_class_context(factory, context)
+ catalog_name = util.class_annotation(factory, 'grok.name', u'')
+ zope.component.provideHandler(
+ IndexesSetupSubscriber(catalog_name, indexes, context),
+ adapts=(grok.interfaces.IApplication,
+ grok.IObjectAddedEvent))
+
+class IndexesSetupSubscriber(object):
+ def __init__(self, catalog_name, indexes, context):
+ self.catalog_name = catalog_name
+ self.indexes = indexes
+ self.context = context
+
+ def __call__(self, app, event):
+ # make sure we have an intids
+ self._createIntIds(app)
+ # get the catalog
+ catalog = self._createCatalog(app)
+ # now install indexes
+ for name, index in self.indexes.items():
+ index.setup(catalog, name, self.context)
+
+ def _createCatalog(self, app):
+ """Create the catalog if needed and return it.
+
+ If the catalog already exists, return that.
+ """
+ catalog = zope.component.queryUtility(
+ ICatalog, name=self.catalog_name, default=None)
+ if catalog is not None:
+ return catalog
+ catalog = Catalog()
+ setupUtility(app, catalog, ICatalog, name=self.catalog_name)
+ return catalog
+
+ def _createIntIds(self, app):
+ """Create intids if needed, and return it.
+ """
+ intids = zope.component.queryUtility(
+ IIntIds, default=None)
+ if intids is not None:
+ return intids
+ intids = IntIds()
+ setupUtility(app, intids, IIntIds)
+ return intids
More information about the Checkins
mailing list