Updated database upgrade code and removed INewLocalSite event subscriber
authorThierry Florac <tflorac@ulthar.net>
Sat, 10 Mar 2018 02:35:43 +0100
changeset 458 7e500a7ecf38
parent 457 f78bfebec3d6
child 459 257b8c748005
Updated database upgrade code and removed INewLocalSite event subscriber
src/pyams_content/generations/__init__.py
--- a/src/pyams_content/generations/__init__.py	Sat Mar 10 02:35:15 2018 +0100
+++ b/src/pyams_content/generations/__init__.py	Sat Mar 10 02:35:43 2018 +0100
@@ -14,6 +14,8 @@
 
 
 # import standard library
+import logging
+logger = logging.getLogger("PyAMS (content)")
 
 # import interfaces
 from pyams_catalog.interfaces import MINUTE_RESOLUTION, DATE_RESOLUTION
@@ -24,13 +26,13 @@
 from pyams_utils.interfaces.traversing import IPathElements
 from pyams_workflow.interfaces import IWorkflowState, IWorkflowPublicationInfo
 from zope.dublincore.interfaces import IZopeDublinCore
-from zope.site.interfaces import INewLocalSite
 
 # import packages
 from hypatia.text.lexicon import Lexicon
 from pyams_catalog.index import FieldIndexWithInterface, KeywordIndexWithInterface, DatetimeIndexWithInterface
 from pyams_catalog.nltk import NltkFullTextProcessor
 from pyams_catalog.site import check_required_indexes
+from pyams_content.reference import ReferencesManager
 from pyams_content.shared.common.manager import SharedToolContainer
 from pyams_content.shared.form.manager import FormsManager
 from pyams_content.shared.imagemap.manager import ImageMapsManager
@@ -41,7 +43,6 @@
 from pyams_security.index import PrincipalsRoleIndex
 from pyams_utils.registry import utility_config, get_global_registry
 from pyams_utils.site import check_required_utilities
-from pyramid.events import subscriber
 from pyramid.path import DottedNameResolver
 from zope.lifecycleevent import ObjectCreatedEvent
 
@@ -52,97 +53,155 @@
 
 REQUIRED_UTILITIES = ()
 
+REQUIRED_TABLES = ()
 
-REQUIRED_TOOLS = [('views', ViewsManager),
-                  ('news', NewsManager),
-                  ('logos', LogosManager),
-                  ('forms', FormsManager),
-                  ('imagemaps', ImageMapsManager)]
+REQUIRED_TOOLS = [
+    ('views', ViewsManager),
+    ('logos', LogosManager),
+    ('imagemaps', ImageMapsManager),
+    ('forms', FormsManager),
+    ('news', NewsManager)
+]
+
+REQUIRED_INDEXES = [
+    ('content_type', FieldIndexWithInterface, {'interface': IBaseContent,
+                                               'discriminator': 'content_type'}),
+    ('role:owner', PrincipalsRoleIndex, {'role_id': 'pyams.Owner'}),
+    ('role:pilot', PrincipalsRoleIndex, {'role_id': 'pyams.Pilot'}),
+    ('role:manager', PrincipalsRoleIndex, {'role_id': 'pyams.Manager'}),
+    ('role:contributor', PrincipalsRoleIndex, {'role_id': 'pyams.Contributor'}),
+    ('role:webmaster', PrincipalsRoleIndex, {'role_id': 'pyams.Webmaster'}),
+    ('parents', KeywordIndexWithInterface, {'interface': IPathElements,
+                                            'discriminator': 'parents'}),
+    ('workflow_state', FieldIndexWithInterface, {'interface': IWorkflowState,
+                                                 'discriminator': 'state'}),
+    ('workflow_principal', FieldIndexWithInterface, {'interface': IWorkflowState,
+                                                     'discriminator': 'state_principal'}),
+    ('modifiers', KeywordIndexWithInterface, {'interface': IWfSharedContent,
+                                              'discriminator': 'modifiers'}),
+    ('created_date', DatetimeIndexWithInterface, {'interface': IZopeDublinCore,
+                                                  'discriminator': 'created',
+                                                  'resolution': DATE_RESOLUTION}),
+    ('modified_date', DatetimeIndexWithInterface, {'interface': IZopeDublinCore,
+                                                   'discriminator': 'modified',
+                                                   'resolution': DATE_RESOLUTION}),
+    ('publication_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
+                                                      'discriminator': 'publication_date',
+                                                      'resolution': MINUTE_RESOLUTION}),
+    ('effective_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
+                                                    'discriminator': 'publication_effective_date',
+                                                    'resolution': MINUTE_RESOLUTION}),
+    ('push_end_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
+                                                   'discriminator': 'push_end_date_index',
+                                                   'resolution': MINUTE_RESOLUTION}),
+    ('expiration_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
+                                                     'discriminator': 'publication_expiration_date',
+                                                     'resolution': MINUTE_RESOLUTION}),
+    ('first_publication_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
+                                                            'discriminator': 'first_publication_date',
+                                                            'resolution': MINUTE_RESOLUTION})
+]
 
 
-REQUIRED_INDEXES = [('content_type', FieldIndexWithInterface, {'interface': IBaseContent,
-                                                               'discriminator': 'content_type'}),
-                    ('role:owner', PrincipalsRoleIndex, {'role_id': 'pyams.Owner'}),
-                    ('role:pilot', PrincipalsRoleIndex, {'role_id': 'pyams.Pilot'}),
-                    ('role:manager', PrincipalsRoleIndex, {'role_id': 'pyams.Manager'}),
-                    ('role:contributor', PrincipalsRoleIndex, {'role_id': 'pyams.Contributor'}),
-                    ('role:webmaster', PrincipalsRoleIndex, {'role_id': 'pyams.Webmaster'}),
-                    ('parents', KeywordIndexWithInterface, {'interface': IPathElements,
-                                                            'discriminator': 'parents'}),
-                    ('workflow_state', FieldIndexWithInterface, {'interface': IWorkflowState,
-                                                                 'discriminator': 'state'}),
-                    ('workflow_principal', FieldIndexWithInterface, {'interface': IWorkflowState,
-                                                                     'discriminator': 'state_principal'}),
-                    ('modifiers', KeywordIndexWithInterface, {'interface': IWfSharedContent,
-                                                              'discriminator': 'modifiers'}),
-                    ('created_date', DatetimeIndexWithInterface, {'interface': IZopeDublinCore,
-                                                                  'discriminator': 'created',
-                                                                  'resolution': DATE_RESOLUTION}),
-                    ('modified_date', DatetimeIndexWithInterface, {'interface': IZopeDublinCore,
-                                                                   'discriminator': 'modified',
-                                                                   'resolution': DATE_RESOLUTION}),
-                    ('publication_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
-                                                                      'discriminator': 'publication_date',
-                                                                      'resolution': MINUTE_RESOLUTION}),
-                    ('effective_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
-                                                                    'discriminator': 'publication_effective_date',
-                                                                    'resolution': MINUTE_RESOLUTION}),
-                    ('push_end_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
-                                                                   'discriminator': 'push_end_date_index',
-                                                                   'resolution': MINUTE_RESOLUTION}),
-                    ('expiration_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
-                                                                     'discriminator': 'publication_expiration_date',
-                                                                     'resolution': MINUTE_RESOLUTION}),
-                    ('first_publication_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
-                                                                            'discriminator': 'first_publication_date',
-                                                                            'resolution': MINUTE_RESOLUTION})]
+#
+# Checker for required shared tables
+#
+
+def check_required_tables(site, tables=REQUIRED_TABLES, registry=None):
+    """Check for required reference tables"""
+
+    def get_tables_manager():
+        # check references tables manager
+        tables_name = tools_configuration.tables_name or \
+                      registry.settings.get('pyams_content.config.tables_name', 'references')
+        if tables_name not in site:
+            logger.info("Creating references table manager...")
+            manager = ReferencesManager()
+            registry.notify(ObjectCreatedEvent(manager))
+            manager.title = {
+                'en': "References tables",
+                'fr': "Tables de références"
+            }
+            manager.short_name = {
+                'en': "References tables",
+                'fr': "Tables de références"
+            }
+            site[tables_name] = manager
+            tools_configuration.tables_name = tables_name
+        else:
+            manager = site[tables_name]
+        return manager
+
+    tools_configuration = ISiteRootToolsConfiguration(site, None)
+    if tools_configuration is not None:
+        if registry is None:
+            registry = get_global_registry()
+        tables_manager = get_tables_manager()
+        for attr, name, factory in tables:
+            table_name = getattr(tools_configuration, attr, None) or \
+                         registry.settings.get('pyams_config.config.{0}'.format(attr), name)
+            if table_name not in tables_manager:
+                table = factory()
+                logger.info("Creating table {0!r}...".format(table))
+                registry.notify(ObjectCreatedEvent(table))
+                tables_manager[table_name] = table
+                setattr(tools_configuration, attr, table_name)
 
 
-def get_tools_manager(site, config, registry=None):
-    """Check for shared tools manager"""
-    if registry is None:
-        registry = get_global_registry()
-    name = config.tools_name or \
-           registry.settings.get('pyams_content.config.tools_name', 'tools')
-    if name not in site:
-        manager = SharedToolContainer()
-        registry.notify(ObjectCreatedEvent(manager))
-        manager.title = {'en': "Shared tools",
-                         'fr': "Outils partagés"}
-        manager.short_name = {'en': "Shared tools",
-                              'fr': "Outils partagés"}
-        manager.navigation_name = {'en': "Shared tools",
-                                   'fr': "Outils partagés"}
-        site[name] = manager
-        config.tools_name = name
-    else:
-        manager = site[name]
-    return manager
-
-
-def get_required_tools(manager, config, tools=REQUIRED_TOOLS, registry=None):
-    """Create required shared tools"""
-    if registry is None:
-        registry = get_global_registry()
-    for name, default_factory in tools:
-        factory = registry.settings.get('pyams_content.config.{name}_tool_factory'.format(name=name))
-        if (factory is None) or (factory.upper() not in ('NONE', '--')):
-            attr_name = '{name}_tool_name'.format(name=name)
-            tool_name = getattr(config, attr_name, None) or \
-                        registry.settings.get('pyams_content.config.{name}'.format(name=attr_name), name)
-            if tool_name not in manager:
-                if factory is not None:
-                    factory = DottedNameResolver().resolve(factory)
-                else:
-                    factory = default_factory
-                tool = factory()
-                registry.notify(ObjectCreatedEvent(tool))
-                manager[tool_name] = tool
-                setattr(config, attr_name, tool_name)
-
+#
+# Checker for required shared tools
+#
 
 def check_required_tools(site, config_interface, tools):
     """Check for required shared tools"""
+
+    def get_tools_manager(site, config, registry=None):
+        """Check for shared tools manager"""
+        if registry is None:
+            registry = get_global_registry()
+        name = config.tools_name or \
+               registry.settings.get('pyams_content.config.tools_name', 'tools')
+        if name not in site:
+            manager = SharedToolContainer()
+            registry.notify(ObjectCreatedEvent(manager))
+            manager.title = {
+                'en': "Shared tools",
+                'fr': "Outils partagés"
+            }
+            manager.short_name = {
+                'en': "Shared tools",
+                'fr': "Outils partagés"
+            }
+            manager.navigation_name = {
+                'en': "Shared tools",
+                'fr': "Outils partagés"
+            }
+            site[name] = manager
+            config.tools_name = name
+        else:
+            manager = site[name]
+        return manager
+
+    def get_required_tools(manager, config, tools=REQUIRED_TOOLS, registry=None):
+        """Create required shared tools"""
+        if registry is None:
+            registry = get_global_registry()
+        for name, default_factory in tools:
+            factory = registry.settings.get('pyams_content.config.{name}_tool_factory'.format(name=name))
+            if (factory is None) or (factory.upper() not in ('NONE', '--')):
+                attr_name = '{name}_tool_name'.format(name=name)
+                tool_name = getattr(config, attr_name, None) or \
+                            registry.settings.get('pyams_content.config.{name}'.format(name=attr_name), name)
+                if tool_name not in manager:
+                    if factory is not None:
+                        factory = DottedNameResolver().resolve(factory)
+                    else:
+                        factory = default_factory
+                    tool = factory()
+                    registry.notify(ObjectCreatedEvent(tool))
+                    manager[tool_name] = tool
+                    setattr(config, attr_name, tool_name)
+
     configuration = config_interface(site, None)
     if configuration is not None:
         # check shared tools manager
@@ -152,6 +211,7 @@
 
 
 def get_required_indexes():
+    """Get list of required indexes based on lexicon settings"""
     indexes = REQUIRED_INDEXES
     registry = get_global_registry()
     for code, language in map(lambda x: x.split(':'),
@@ -164,23 +224,16 @@
     return indexes
 
 
-@subscriber(INewLocalSite)
-def handle_new_local_site(event):
-    """Check for required utilities when a site is created"""
-    site = event.manager.__parent__
-    check_required_utilities(site, REQUIRED_UTILITIES)
-    check_required_indexes(site, get_required_indexes())
-    check_required_tools(site, ISiteRootToolsConfiguration, REQUIRED_TOOLS)
-
-
 @utility_config(name='PyAMS content', provides=ISiteGenerations)
 class WebsiteGenerationsChecker(object):
     """PyAMS content package generations checker"""
 
+    order = 100
     generation = 1
 
     def evolve(self, site, current=None):
-        """Check for required utilities"""
+        """Check for required utilities, tables and tools"""
         check_required_utilities(site, REQUIRED_UTILITIES)
         check_required_indexes(site, get_required_indexes())
+        check_required_tables(site, REQUIRED_TABLES)
         check_required_tools(site, ISiteRootToolsConfiguration, REQUIRED_TOOLS)