# HG changeset patch # User Thierry Florac # Date 1605268904 -3600 # Node ID 60d14cecb200eaf0203ad31aa3e5f8e6f0a14882 # Parent 31c1bc24a3084beae72cc8ed843a09d6c5b67160 Added hubs management diff -r 31c1bc24a308 -r 60d14cecb200 src/pyams_content/shared/hub/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/hub/__init__.py Fri Nov 13 13:01:44 2020 +0100 @@ -0,0 +1,17 @@ +# +# Copyright (c) 2015-2020 Thierry Florac +# 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. +# + +"""PyAMS_*** module + +""" + +__docformat__ = 'restructuredtext' diff -r 31c1bc24a308 -r 60d14cecb200 src/pyams_content/shared/hub/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/hub/interfaces.py Fri Nov 13 13:01:44 2020 +0100 @@ -0,0 +1,44 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# 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. +# + +from collections import OrderedDict + +from zope.annotation.interfaces import IAttributeAnnotatable +from zope.container.constraints import containers, contains +from zope.container.interfaces import IContained, IContainer +from zope.interface import Attribute, Interface +from zope.schema import Bool, Choice, Text, URI +from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary + +from pyams_content.interfaces import IBaseContent +from pyams_content.shared.common.interfaces import IBaseContentManagerRoles, IBaseSharedTool, \ + IDeletableElement, ISharedSite +from pyams_content.shared.common.interfaces.types import DATA_TYPES_VOCABULARY +from pyams_content.shared.site.interfaces import ISiteManager +from pyams_content.shared.topic.interfaces import ITopic, IWfTopic, IWfTopicFactory +from pyams_i18n.schema import I18nTextField, I18nTextLineField +from pyams_sequence.interfaces import IInternalReference, IInternalReferencesList, \ + ISequentialIdTarget +from pyams_workflow.interfaces import IWorkflowPublicationSupport + + +__docformat__ = 'restructuredtext' + +from pyams_content import _ + + +class IHubManager(ISiteManager): + """Hub manager interface""" + + +class IHubManagerFactory(Interface): + """Hub manager factory interface""" diff -r 31c1bc24a308 -r 60d14cecb200 src/pyams_content/shared/hub/manager.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/hub/manager.py Fri Nov 13 13:01:44 2020 +0100 @@ -0,0 +1,94 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# 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. +# + +from zope.container.ordered import OrderedContainer +from zope.interface import implementer +from zope.schema.fieldproperty import FieldProperty + +from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget +from pyams_content.component.paragraph import IParagraphContainerTarget +from pyams_content.component.paragraph.interfaces import IParagraphFactorySettings +from pyams_content.component.theme import ITagsTarget, IThemesTarget +from pyams_content.component.theme.interfaces import ICollectionsManagerTarget, \ + IThemesManagerTarget +from pyams_content.features.footer.interfaces import IFooterTarget +from pyams_content.features.header.interfaces import IHeaderTarget +from pyams_content.features.preview.interfaces import IPreviewTarget +from pyams_content.reference.pictograms.interfaces import IPictogramManagerTarget +from pyams_content.root.interfaces import ISiteRoot +from pyams_content.shared.common.interfaces import ISharedContentFactory +from pyams_content.shared.common.manager import BaseSharedTool +from pyams_content.shared.common.types import TypedSharedToolMixin +from pyams_content.shared.hub.interfaces import IHubManager, IHubManagerFactory +from pyams_content.shared.site.container import SiteContainerMixin +from pyams_content.shared.site.folder import SiteFolder +from pyams_content.shared.site.interfaces import ISiteFolderFactory +from pyams_portal.interfaces import IPortalContext +from pyams_skin.skin import UserSkinnableContent +from pyams_utils.adapter import adapter_config + + +__docformat__ = 'restructuredtext' + +from pyams_content import _ + + +@implementer(IHubManager, IParagraphFactorySettings, IParagraphContainerTarget, + IThemesManagerTarget, ICollectionsManagerTarget, IPictogramManagerTarget, + ITagsTarget, IThemesTarget, + IIllustrationTarget, ILinkIllustrationTarget, IPortalContext, IHeaderTarget, + IFooterTarget, IPreviewTarget) +class HubManager(SiteContainerMixin, OrderedContainer, BaseSharedTool, TypedSharedToolMixin, + UserSkinnableContent): + """Hub manager persistent class""" + + header = FieldProperty(IHubManager['header']) + description = FieldProperty(IHubManager['description']) + notepad = FieldProperty(IHubManager['notepad']) + + allowed_paragraphs = FieldProperty(IParagraphFactorySettings['allowed_paragraphs']) + auto_created_paragraphs = FieldProperty(IParagraphFactorySettings['auto_created_paragraphs']) + + sequence_name = '' # use default sequence generator + sequence_prefix = '' + + content_name = _("Hub manager") + + @property + def folder_factory(self): + return ISiteFolderFactory(self, SiteFolder) + + @property + def topic_content_factory(self): + return ISharedContentFactory(self, None) + + @property + def topic_content_type(self): + factory = self.topic_content_factory + if factory is not None: + return factory.content_class.content_type + + def is_deletable(self): + for element in self.values(): + if not element.is_deletable(): + return False + return True + + +@adapter_config(context=ISiteRoot, provides=IHubManagerFactory) +def site_root_hub_manager_factory(context): + return HubManager + + +@adapter_config(context=IHubManager, provides=ISiteFolderFactory) +def hub_manager_folder_factory(context): + return SiteFolder diff -r 31c1bc24a308 -r 60d14cecb200 src/pyams_content/shared/hub/zmi/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/hub/zmi/__init__.py Fri Nov 13 13:01:44 2020 +0100 @@ -0,0 +1,17 @@ +# +# Copyright (c) 2015-2020 Thierry Florac +# 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. +# + +"""PyAMS_*** module + +""" + +__docformat__ = 'restructuredtext' diff -r 31c1bc24a308 -r 60d14cecb200 src/pyams_content/shared/hub/zmi/manager.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/shared/hub/zmi/manager.py Fri Nov 13 13:01:44 2020 +0100 @@ -0,0 +1,111 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# 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. +# + +from pyramid.path import DottedNameResolver +from z3c.form import field + +from pyams_content.interfaces import MANAGE_SITE_ROOT_PERMISSION, MANAGE_TOOL_PERMISSION +from pyams_content.root.interfaces import ISiteRoot +from pyams_content.shared.common import IBaseSharedTool, IDashboardTypeColumnValue +from pyams_content.shared.common.interfaces.zmi import IDashboardTable +from pyams_content.shared.common.zmi.manager import SharedToolPropertiesEditForm +from pyams_content.shared.hub.interfaces import IHubManager, IHubManagerFactory +from pyams_content.shared.hub.manager import HubManager +from pyams_content.zmi.interfaces import ISiteTreeTable +from pyams_form.form import AJAXAddForm, ajax_config +from pyams_i18n.interfaces import II18n +from pyams_pagelet.pagelet import pagelet_config +from pyams_skin.interfaces.viewlet import IMenuHeader, IToolbarAddingMenu +from pyams_skin.layer import IPyAMSLayer +from pyams_skin.viewlet.toolbar import ToolbarMenuItem +from pyams_utils.adapter import ContextRequestAdapter, adapter_config +from pyams_utils.unicode import translate_string +from pyams_utils.url import absolute_url +from pyams_viewlet.viewlet import viewlet_config +from pyams_zmi.form import AdminDialogAddForm +from pyams_zmi.interfaces.menu import ISiteManagementMenu +from pyams_zmi.layer import IAdminLayer + + +__docformat__ = 'restructuredtext' + +from pyams_content import _ + + +@adapter_config(context=(IHubManager, IPyAMSLayer, IDashboardTable), + provides=IDashboardTypeColumnValue) +def hub_manager_dashboard_type(context, request, view): + """Site manager dashboard type column adapter""" + return request.localizer.translate(context.content_name) + + +@adapter_config(context=(IHubManager, ISiteManagementMenu), provides=IMenuHeader) +class HubManagerSiteManagementMenuHeader(ContextRequestAdapter): + """Hub manager site management menu header adapter""" + + header = _("Hub management") + + +@viewlet_config(name='add-hub-manager.menu', context=ISiteRoot, layer=IAdminLayer, + view=ISiteTreeTable, manager=IToolbarAddingMenu, + permission=MANAGE_SITE_ROOT_PERMISSION) +class HubManagerAddMenu(ToolbarMenuItem): + """Hub manager add menu""" + + label = _("Add hub manager") + label_css_class = 'fa fa-fw fa-shopping-basket' + url = 'add-hub-manager.html' + modal_target = True + + +@pagelet_config(name='add-hub-manager.html', context=ISiteRoot, layer=IPyAMSLayer, + permission=MANAGE_SITE_ROOT_PERMISSION) +@ajax_config(name='add-hub-manager.json', context=ISiteRoot, layer=IPyAMSLayer, + permission=MANAGE_SITE_ROOT_PERMISSION, base=AJAXAddForm) +class HubManagerAddForm(AdminDialogAddForm): + """Hub manager add form""" + + title = _("Hub manager") + legend = _("Add hub manager") + icon_css_class = 'fa fa-fw fa-shopping-basket' + + fields = field.Fields(IHubManager).select('title', 'short_name') + edit_permission = None + + def create(self, data): + factory = self.request.registry.settings.get('pyams_content.config.hub_factory') + if factory: + factory = DottedNameResolver().resolve(factory) + else: + factory = IHubManagerFactory(self.context, HubManager) + return factory() + + def add(self, object): + short_name = II18n(object).query_attribute('short_name', request=self.request) + name = translate_string(short_name, force_lower=True, spaces='-') + self.context[name] = object + + def nextURL(self): + return absolute_url(self.context, self.request, 'site-tree.html') + + +@pagelet_config(name='properties.html', context=IHubManager, layer=IPyAMSLayer, + permission=MANAGE_TOOL_PERMISSION) +@ajax_config(name='properties.json', context=IHubManager, layer=IPyAMSLayer) +class HubManagerPropertiesEditForm(SharedToolPropertiesEditForm): + """Hub manager properties edit form""" + + legend = _("Hub manager properties") + + fields = field.Fields(IHubManager).select('title', 'short_name', 'header', 'description', + 'notepad') + \ + field.Fields(IBaseSharedTool).select('shared_content_workflow')