--- a/src/pyams_zmi/control_panel.py Sat Feb 28 16:20:01 2015 +0100
+++ b/src/pyams_zmi/control_panel.py Tue Mar 03 16:53:26 2015 +0100
@@ -14,10 +14,12 @@
# import standard library
+from html import escape
# import interfaces
from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentHelp
from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces.site import IOptionalUtility
from pyams_zmi.interfaces.menu import IControlPanelMenu, IUtilitiesMenu
from pyams_zmi.layer import IAdminLayer
from z3c.table.interfaces import IValues, IColumn
@@ -27,15 +29,18 @@
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.container import ContainerView
from pyams_skin.help import ContentHelp
-from pyams_skin.table import BaseTable
+from pyams_skin.table import BaseTable, TrashColumn
from pyams_skin.viewlet.menu import MenuItem
from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
+from pyams_utils.registry import registered_utilities
from pyams_utils.text import text_to_html
+from pyams_utils.url import absolute_url
from pyams_viewlet.manager import viewletmanager_config
from pyams_viewlet.viewlet import viewlet_config
from pyams_zmi.view import AdminView
+from pyramid.view import view_config
from z3c.table.column import GetAttrColumn
-from zope.interface import implementer
+from zope.interface import implementer, Interface
from pyams_zmi import _
@@ -63,6 +68,23 @@
title = _("Site utilities")
cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight datatable'}
+ @property
+ def data_attributes(self):
+ attrs = super(UtilitiesTable, self).data_attributes
+ attrs['table'] = {'data-ams-location': absolute_url(self.context, self.request),
+ 'data-ams-delete-target': 'delete-utility.json'}
+ return attrs
+
+
+@adapter_config(name='trash', context=(Interface, IAdminLayer, UtilitiesTable), provides=IColumn)
+class UtilitiesTrashColumn(TrashColumn):
+ """Utilities trash column"""
+
+ icon_hint = _("Delete utility")
+ permission = 'system.manage'
+
+ checker = lambda col, x: IOptionalUtility.providedBy(x)
+
@adapter_config(context=(ISite, IAdminLayer, UtilitiesTable), provides=IValues)
class UtilitiesValuesAdapter(ContextRequestViewAdapter):
@@ -93,38 +115,34 @@
subtitle = _("Utilities")
-#
-# Registrations views and adapters
-#
-
-@viewlet_config(name='registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
- permission='system.view', weight=1)
-class RegistrationsMenuItem(MenuItem):
- """Registrations menu"""
-
- label = _("Registrations")
- url = '#registrations.html'
+@view_config(name='delete-utility.json', context=ISite, request_type=IPyAMSLayer,
+ permission='system.manage', renderer='json', xhr=True)
+def delete_utility(request):
+ """Delete utility from site manager"""
+ translate = request.localizer.translate
+ name = request.params.get('object_name')
+ if not name:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("No provided object_name argument!"))}}
+ manager = request.context.getSiteManager()
+ if name not in manager:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("Given utility name doesn't exist!"))}}
+ del manager[name]
+ return {'status': 'success'}
-class RegistrationsTable(BaseTable):
- """Utilities registrations table"""
+#
+# Common registrations views and adapters
+#
- id = 'registrations_table'
- title = _("Utilities registrations")
-
- data_attributes = {}
+class IRegistrationsTable(Interface):
+ """Registrations view marker interface"""
-@adapter_config(context=(ISite, IAdminLayer, RegistrationsTable), provides=IValues)
-class RegistrationsValuesAdapter(ContextRequestViewAdapter):
- """Utilities values adapter"""
-
- @property
- def values(self):
- return list(self.context.getSiteManager().registeredUtilities())
-
-
-@adapter_config(name='component', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
+@adapter_config(name='component', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
class RegistrationsComponentColumn(GetAttrColumn):
"""Registrations component column"""
@@ -136,10 +154,17 @@
return self.request.localizer.translate(self._header)
def getValue(self, obj):
- return obj.component.__name__
+ component = obj.component
+ if component is not None:
+ name = getattr(component, '__name__', None)
+ if not name:
+ name = str(component.__class__)
+ else:
+ name = str(obj.factory)
+ return escape(name)
-@adapter_config(name='interface', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
+@adapter_config(name='interface', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
class RegistrationsInterfaceColumn(GetAttrColumn):
"""Registrations interface column"""
@@ -154,7 +179,7 @@
return text_to_html(str(obj.provided))
-@adapter_config(name='name', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
+@adapter_config(name='name', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
class RegistrationsNameColumn(GetAttrColumn):
"""Registrations name column"""
@@ -169,29 +194,61 @@
return obj.name or _('< no name >')
-@pagelet_config(name='registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
+#
+# Local registrations views
+#
+
+@viewlet_config(name='local-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
+ permission='system.view', weight=1)
+class LocalRegistrationsMenuItem(MenuItem):
+ """Local registrations menu"""
+
+ label = _("Local registrations")
+ url = '#local-registrations.html'
+
+
+@implementer(IRegistrationsTable)
+class LocalRegistrationsTable(BaseTable):
+ """Local utilities registrations table"""
+
+ id = 'local_registrations_table'
+ title = _("Local utilities registrations")
+
+ data_attributes = {}
+
+
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsTable), provides=IValues)
+class LocalRegistrationsValuesAdapter(ContextRequestViewAdapter):
+ """Local utilities values adapter"""
+
+ @property
+ def values(self):
+ return list(self.context.getSiteManager().registeredUtilities())
+
+
+@pagelet_config(name='local-registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
@implementer(IInnerPage)
-class RegistrationsView(AdminView, ContainerView):
+class LocalRegistrationsView(AdminView, ContainerView):
"""Registrations view"""
- table_class = RegistrationsTable
+ table_class = LocalRegistrationsTable
def __init__(self, context, request):
- super(RegistrationsView, self).__init__(context, request)
+ super(LocalRegistrationsView, self).__init__(context, request)
-@adapter_config(context=(ISite, IAdminLayer, RegistrationsView), provides=IPageHeader)
-class RegistrationsHeaderAdapter(ContextRequestViewAdapter):
- """Registrations header adapter"""
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IPageHeader)
+class LocalRegistrationsHeaderAdapter(ContextRequestViewAdapter):
+ """Local registrations header adapter"""
icon_class = 'fa fa-fw fa-codepen'
title = _("Control panel")
subtitle = _("Local utilities registry")
-@adapter_config(context=(ISite, IAdminLayer, RegistrationsView), provides=IContentHelp)
-class RegistrationsHelpAdapter(ContentHelp):
- """Registrations help adapter"""
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IContentHelp)
+class LocalRegistrationsHelpAdapter(ContentHelp):
+ """Local registrations help adapter"""
header = _("Local registry utilities")
message = _("""A local registry is a registry defining utilities stored into
@@ -200,3 +257,68 @@
You can manage these utilities and modify their properties and site's behaviour without
modifying the application.""")
message_format = 'rest'
+
+
+#
+# Global registrations views
+#
+
+@viewlet_config(name='global-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
+ permission='system.view', weight=2)
+class GlobalRegistrationsMenuItem(MenuItem):
+ """Global registrations menu"""
+
+ label = _("Global registrations")
+ url = '#global-registrations.html'
+
+
+@implementer(IRegistrationsTable)
+class GlobalRegistrationsTable(BaseTable):
+ """Utilities global registrations table"""
+
+ id = 'global_registrations_table'
+ title = _("Global utilities registrations")
+
+ data_attributes = {}
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsTable), provides=IValues)
+class GlobalRegistrationsValuesAdapter(ContextRequestViewAdapter):
+ """Global utilities values adapter"""
+
+ @property
+ def values(self):
+ return list(registered_utilities())
+
+
+@pagelet_config(name='global-registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
+@implementer(IInnerPage)
+class GlobalRegistrationsView(AdminView, ContainerView):
+ """Global registrations view"""
+
+ table_class = GlobalRegistrationsTable
+
+ def __init__(self, context, request):
+ super(GlobalRegistrationsView, self).__init__(context, request)
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IPageHeader)
+class GlobalRegistrationsHeaderAdapter(ContextRequestViewAdapter):
+ """Global registrations header adapter"""
+
+ icon_class = 'fa fa-fw fa-codepen'
+ title = _("Control panel")
+ subtitle = _("Global utilities registry")
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IContentHelp)
+class GlobalRegistrationsHelpAdapter(ContentHelp):
+ """Global registrations help adapter"""
+
+ header = _("Global registry utilities")
+ message = _("""The global registry groups local utilities as well as utilities registered outside
+site's Object Database (ZODB).
+
+These utilities are declared statically (generally using include or ZCML directives) and can't be setup
+without modifying site configuration.""")
+ message_format = 'rest'