source: main/waeup.sirp/trunk/src/waeup/sirp/meta.py @ 6138

Last change on this file since 6138 was 6138, checked in by uli, 13 years ago

Make a possibility to update/create catalogs in a running site.

File size: 4.6 KB
Line 
1##
2## meta.py
3## Login : <uli@pu.smp.net>
4## Started on  Wed May 18 23:38:13 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""Grokkers for WAeUP components.
23
24Stuff in here is mainly taken from grok.meta, with some modifications
25to provide a possibility to update catalogs in a running site. This is
26to solve the very common problem of already running sites for which
27the software changes and adds catalogs. These catalogs will not be
28automatically added in a running site.
29
30With the following Grokker and the upgrade helper class we can fire
31IObjectUpgradedEvents for any existing site and all catalogs
32registered will be really created.
33
34Please note that yet these catalogs are not filled automatically! That
35means the catalogs will exist but are empty in the beginning.
36
37We might solve this second problem by firing extra events like some
38ICatalogUpdatedEvent (which still do not exist) or similar.
39"""
40import grok
41import martian
42from grok import components
43from grok.meta import IndexesSetupSubscriber
44from martian.error import GrokError
45from zope import component
46from waeup.sirp.interfaces import IObjectUpgradeEvent
47
48class IndexesGrokker(martian.InstanceGrokker):
49    """Grokker for Grok index bundles."""
50    martian.component(components.IndexesClass)
51
52    def grok(self, name, factory, module_info, config, **kw):
53        site = grok.site.bind().get(factory)
54        context = grok.context.bind().get(factory, module_info.getModule())
55        catalog_name = grok.name.bind().get(factory)
56
57        if site is None:
58            raise GrokError("No site specified for grok.Indexes "
59                            "subclass in module %r. "
60                            "Use grok.site() to specify."
61                            % module_info.getModule(),
62                            factory)
63        indexes = getattr(factory, '__grok_indexes__', None)
64        if indexes is None:
65            return False
66
67        subscriber = WAeUPIndexesSetupSubscriber(
68            catalog_name, indexes, context, module_info)
69        subscribed = (site, IObjectUpgradeEvent)
70        config.action(
71            discriminator=None,
72            callable=component.provideHandler,
73            args=(subscriber, subscribed),
74            )
75        return True
76
77
78class WAeUPIndexesUpgradeSubscriber(IndexesSetupSubscriber):
79    """Helper that sets up indexes when their Grok site is upgraded.
80
81    Each `grok.Indexes` class serves as an assertion that, whenever an
82    instance of its `grok.site()` is upgraded, the given list of
83    indexes should be generated if not already created as well.  But a
84    long period of time could elapse between when the application
85    starts (and its indexes are grokked), and the moment, maybe days
86    or weeks later, when a new instance of that `grok.Site` is
87    created.  Hence this `IndexesSetupSubscriber`: it can be
88    instantiated at grokking time with the index information, and then
89    registered with the Component Architecture as an event that should
90    be fired later, whenever the right kind of `grok.Site` is
91    instantiated.  At that point its `__call__` method is kicked off
92    and it makes sure the index catalogs get created properly.
93
94    """
95    def __call__(self, site, event):
96        site.logger.info('Create catalog `%s` if not installed yet.'  % (
97                self.catalog_name,))
98        # make sure we have an intids
99        self._createIntIds(site)
100        # get the catalog
101        catalog = self._createCatalog(site)
102        # now install indexes
103        for name, index in self.indexes.items():
104            try:
105                site.logger.info('Create index `%s` in catalog' % name)
106                index.setup(catalog, name, self.context, self.module_info)
107                site.logger.info('index created.')
108            except KeyError: #, DuplicationError:
109                site.logger.info('index `%s` already in catalog' % name)
110                pass
111        site.logger.info('Catalog `%s` ready.' % self.catalog_name)
Note: See TracBrowser for help on using the repository browser.