src/pyams_skin/configuration.py
changeset 557 bca7a7e058a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_skin/configuration.py	Thu Feb 13 11:43:31 2020 +0100
@@ -0,0 +1,156 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+from pyramid.httpexceptions import HTTPNotFound
+from pyramid.view import view_config
+from zope.container.contained import Contained
+from zope.interface import Interface, implementer
+from zope.schema.fieldproperty import FieldProperty
+from zope.traversing.interfaces import ITraversable
+
+from pyams_file.property import FileProperty
+from pyams_file.views.file import FileView
+from pyams_skin.interfaces import IContextTitlePrefix
+from pyams_skin.interfaces.configuration import IBackOfficeConfiguration, IConfiguration, SKIN_BACK_CONFIGURATION_KEY, \
+    SKIN_CONFIGURATION_KEY
+from pyams_utils.adapter import ContextAdapter, ContextRequestViewAdapter, adapter_config, get_annotation_adapter
+from pyams_utils.factory import factory_config
+from pyams_utils.interfaces.site import IConfigurationManager
+from pyams_utils.interfaces.tales import ITALESExtension
+from pyams_utils.registry import get_global_registry
+from pyams_utils.traversing import get_parent
+
+
+#
+# Dynamic front-office configuration
+# May be overriden by custom applications
+#
+
+@factory_config(IConfiguration)
+class Configuration(Persistent, Contained):
+    """Manageable configuration"""
+
+    title = FieldProperty(IConfiguration['title'])
+    short_title = FieldProperty(IConfiguration['short_title'])
+    description = FieldProperty(IConfiguration['description'])
+    author = FieldProperty(IConfiguration['author'])
+    icon = FileProperty(IConfiguration['icon'])
+    logo = FileProperty(IConfiguration['logo'])
+
+    @staticmethod
+    def get_title_prefix(request):
+        adapter = get_global_registry().queryMultiAdapter((request.context, request), IContextTitlePrefix)
+        if adapter is not None:
+            return adapter.prefix
+
+
+@adapter_config(context=IConfigurationManager, provides=IConfiguration)
+def configuration_factory(context):
+    """Configuration factory"""
+    return get_annotation_adapter(context, SKIN_CONFIGURATION_KEY, IConfiguration,
+                                  name='++configuration++')
+
+
+@adapter_config(name='configuration', context=(Interface, Interface, Interface), provides=ITALESExtension)
+class ConfigurationTalesExtension(ContextRequestViewAdapter):
+    """extension:configuration TALES expression"""
+
+    def render(self, context=None):
+        if context is None:
+            context = self.context
+        manager = get_parent(context, IConfigurationManager)
+        if manager is not None:
+            return IConfiguration(manager)
+
+
+@adapter_config(name='configuration', context=IConfigurationManager, provides=ITraversable)
+class ConfigurationTraverser(ContextAdapter):
+    """++configuration++ namespace traverser"""
+
+    def traverse(self, name, furtherpath=None):
+        return IConfiguration(self.context)
+
+
+@view_config(name='favicon.ico', context=IConfigurationManager)
+def site_icon(request):
+    configuration = IConfiguration(request.context)
+    if configuration.icon is not None:
+        request = request.copy()
+        request.context = configuration.icon
+        return FileView(request)
+    return HTTPNotFound()
+
+
+#
+# Dynamic back-office configuration
+# May be overriden by custom applications
+#
+
+@factory_config(IBackOfficeConfiguration)
+class BackOfficeConfiguration(Persistent, Contained):
+    """Back-office manageable configuration"""
+
+    title = FieldProperty(IBackOfficeConfiguration['title'])
+    short_title = FieldProperty(IBackOfficeConfiguration['short_title'])
+    login_header = FieldProperty(IBackOfficeConfiguration['login_header'])
+    login_footer = FieldProperty(IBackOfficeConfiguration['login_footer'])
+    icon = FileProperty(IBackOfficeConfiguration['icon'])
+    logo = FileProperty(IBackOfficeConfiguration['logo'])
+    login_logo = FileProperty(IBackOfficeConfiguration['login_logo'])
+    display_content_icon = FieldProperty(IBackOfficeConfiguration['display_content_icon'])
+    display_shared_tool_title = FieldProperty(IBackOfficeConfiguration['display_shared_tool_title'])
+
+    @staticmethod
+    def get_title_prefix(request):
+        adapter = request.registry.queryMultiAdapter((request.context, request), IContextTitlePrefix)
+        if adapter is not None:
+            return adapter.prefix
+
+
+@adapter_config(context=IConfigurationManager, provides=IBackOfficeConfiguration)
+def back_office_configuration_factory(context):
+    """Back-office configuration factory"""
+    return get_annotation_adapter(context, SKIN_BACK_CONFIGURATION_KEY, IBackOfficeConfiguration,
+                                  name='++back-configuration++')
+
+
+@adapter_config(name='back_configuration', context=(Interface, Interface, Interface), provides=ITALESExtension)
+class BackOfficeConfigurationTalesExtension(ContextRequestViewAdapter):
+    """extension:back_configuration TALES expression"""
+
+    def render(self, context=None):
+        if context is None:
+            context = self.context
+        manager = get_parent(context, IConfigurationManager)
+        if manager is not None:
+            return IBackOfficeConfiguration(manager)
+
+
+@adapter_config(name='back-configuration', context=IConfigurationManager, provides=ITraversable)
+class BackOfficeConfigurationTraverser(ContextAdapter):
+    """++back-configuration++ namespace traverser"""
+
+    def traverse(self, name, furtherpath=None):
+        return IBackOfficeConfiguration(self.context)
+
+
+@view_config(name='back-favicon.ico', context=IConfigurationManager)
+def back_office_site_icon(request):
+    configuration = IBackOfficeConfiguration(request.context)
+    if configuration.icon is not None:
+        request = request.copy()
+        request.context = configuration.icon
+        return FileView(request)
+    return HTTPNotFound()