src/pyams_zmi/control_panel.py
changeset 3 b284b151f292
parent 0 9131229e2982
child 4 0ff044965637
equal deleted inserted replaced
2:bc1d70f9a9e2 3:b284b151f292
    12 
    12 
    13 __docformat__ = 'restructuredtext'
    13 __docformat__ = 'restructuredtext'
    14 
    14 
    15 
    15 
    16 # import standard library
    16 # import standard library
       
    17 from html import escape
    17 
    18 
    18 # import interfaces
    19 # import interfaces
    19 from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentHelp
    20 from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentHelp
    20 from pyams_skin.layer import IPyAMSLayer
    21 from pyams_skin.layer import IPyAMSLayer
       
    22 from pyams_utils.interfaces.site import IOptionalUtility
    21 from pyams_zmi.interfaces.menu import IControlPanelMenu, IUtilitiesMenu
    23 from pyams_zmi.interfaces.menu import IControlPanelMenu, IUtilitiesMenu
    22 from pyams_zmi.layer import IAdminLayer
    24 from pyams_zmi.layer import IAdminLayer
    23 from z3c.table.interfaces import IValues, IColumn
    25 from z3c.table.interfaces import IValues, IColumn
    24 from zope.component.interfaces import ISite
    26 from zope.component.interfaces import ISite
    25 
    27 
    26 # import packages
    28 # import packages
    27 from pyams_pagelet.pagelet import pagelet_config
    29 from pyams_pagelet.pagelet import pagelet_config
    28 from pyams_skin.container import ContainerView
    30 from pyams_skin.container import ContainerView
    29 from pyams_skin.help import ContentHelp
    31 from pyams_skin.help import ContentHelp
    30 from pyams_skin.table import BaseTable
    32 from pyams_skin.table import BaseTable, TrashColumn
    31 from pyams_skin.viewlet.menu import MenuItem
    33 from pyams_skin.viewlet.menu import MenuItem
    32 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
    34 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
       
    35 from pyams_utils.registry import registered_utilities
    33 from pyams_utils.text import text_to_html
    36 from pyams_utils.text import text_to_html
       
    37 from pyams_utils.url import absolute_url
    34 from pyams_viewlet.manager import viewletmanager_config
    38 from pyams_viewlet.manager import viewletmanager_config
    35 from pyams_viewlet.viewlet import viewlet_config
    39 from pyams_viewlet.viewlet import viewlet_config
    36 from pyams_zmi.view import AdminView
    40 from pyams_zmi.view import AdminView
       
    41 from pyramid.view import view_config
    37 from z3c.table.column import GetAttrColumn
    42 from z3c.table.column import GetAttrColumn
    38 from zope.interface import implementer
    43 from zope.interface import implementer, Interface
    39 
    44 
    40 from pyams_zmi import _
    45 from pyams_zmi import _
    41 
    46 
    42 
    47 
    43 #
    48 #
    61 
    66 
    62     id = 'utilities_table'
    67     id = 'utilities_table'
    63     title = _("Site utilities")
    68     title = _("Site utilities")
    64     cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight datatable'}
    69     cssClasses = {'table': 'table table-bordered table-striped table-hover table-tight datatable'}
    65 
    70 
       
    71     @property
       
    72     def data_attributes(self):
       
    73         attrs = super(UtilitiesTable, self).data_attributes
       
    74         attrs['table'] = {'data-ams-location': absolute_url(self.context, self.request),
       
    75                           'data-ams-delete-target': 'delete-utility.json'}
       
    76         return attrs
       
    77 
       
    78 
       
    79 @adapter_config(name='trash', context=(Interface, IAdminLayer, UtilitiesTable), provides=IColumn)
       
    80 class UtilitiesTrashColumn(TrashColumn):
       
    81     """Utilities trash column"""
       
    82 
       
    83     icon_hint = _("Delete utility")
       
    84     permission = 'system.manage'
       
    85 
       
    86     checker = lambda col, x: IOptionalUtility.providedBy(x)
       
    87 
    66 
    88 
    67 @adapter_config(context=(ISite, IAdminLayer, UtilitiesTable), provides=IValues)
    89 @adapter_config(context=(ISite, IAdminLayer, UtilitiesTable), provides=IValues)
    68 class UtilitiesValuesAdapter(ContextRequestViewAdapter):
    90 class UtilitiesValuesAdapter(ContextRequestViewAdapter):
    69     """Utilities values adapter"""
    91     """Utilities values adapter"""
    70 
    92 
    91     icon_class = 'fa fa-fw fa-codepen'
   113     icon_class = 'fa fa-fw fa-codepen'
    92     title = _("Control panel")
   114     title = _("Control panel")
    93     subtitle = _("Utilities")
   115     subtitle = _("Utilities")
    94 
   116 
    95 
   117 
    96 #
   118 @view_config(name='delete-utility.json', context=ISite, request_type=IPyAMSLayer,
    97 # Registrations views and adapters
   119              permission='system.manage', renderer='json', xhr=True)
    98 #
   120 def delete_utility(request):
    99 
   121     """Delete utility from site manager"""
   100 @viewlet_config(name='registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
   122     translate = request.localizer.translate
       
   123     name = request.params.get('object_name')
       
   124     if not name:
       
   125         return {'status': 'message',
       
   126                 'messagebox': {'status': 'error',
       
   127                                'content': translate(_("No provided object_name argument!"))}}
       
   128     manager = request.context.getSiteManager()
       
   129     if name not in manager:
       
   130         return {'status': 'message',
       
   131                 'messagebox': {'status': 'error',
       
   132                                'content': translate(_("Given utility name doesn't exist!"))}}
       
   133     del manager[name]
       
   134     return {'status': 'success'}
       
   135 
       
   136 
       
   137 #
       
   138 # Common registrations views and adapters
       
   139 #
       
   140 
       
   141 class IRegistrationsTable(Interface):
       
   142     """Registrations view marker interface"""
       
   143 
       
   144 
       
   145 @adapter_config(name='component', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
       
   146 class RegistrationsComponentColumn(GetAttrColumn):
       
   147     """Registrations component column"""
       
   148 
       
   149     _header = _("Component")
       
   150     weight = 1
       
   151 
       
   152     @property
       
   153     def header(self):
       
   154         return self.request.localizer.translate(self._header)
       
   155 
       
   156     def getValue(self, obj):
       
   157         component = obj.component
       
   158         if component is not None:
       
   159             name = getattr(component, '__name__', None)
       
   160             if not name:
       
   161                 name = str(component.__class__)
       
   162         else:
       
   163             name = str(obj.factory)
       
   164         return escape(name)
       
   165 
       
   166 
       
   167 @adapter_config(name='interface', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
       
   168 class RegistrationsInterfaceColumn(GetAttrColumn):
       
   169     """Registrations interface column"""
       
   170 
       
   171     _header = _("Registered interface")
       
   172     weight = 5
       
   173 
       
   174     @property
       
   175     def header(self):
       
   176         return self.request.localizer.translate(self._header)
       
   177 
       
   178     def getValue(self, obj):
       
   179         return text_to_html(str(obj.provided))
       
   180 
       
   181 
       
   182 @adapter_config(name='name', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
       
   183 class RegistrationsNameColumn(GetAttrColumn):
       
   184     """Registrations name column"""
       
   185 
       
   186     _header = _("Name")
       
   187     weight = 10
       
   188 
       
   189     @property
       
   190     def header(self):
       
   191         return self.request.localizer.translate(self._header)
       
   192 
       
   193     def getValue(self, obj):
       
   194         return obj.name or _('< no name >')
       
   195 
       
   196 
       
   197 #
       
   198 # Local registrations views
       
   199 #
       
   200 
       
   201 @viewlet_config(name='local-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
   101                 permission='system.view', weight=1)
   202                 permission='system.view', weight=1)
   102 class RegistrationsMenuItem(MenuItem):
   203 class LocalRegistrationsMenuItem(MenuItem):
   103     """Registrations menu"""
   204     """Local registrations menu"""
   104 
   205 
   105     label = _("Registrations")
   206     label = _("Local registrations")
   106     url = '#registrations.html'
   207     url = '#local-registrations.html'
   107 
   208 
   108 
   209 
   109 class RegistrationsTable(BaseTable):
   210 @implementer(IRegistrationsTable)
   110     """Utilities registrations table"""
   211 class LocalRegistrationsTable(BaseTable):
   111 
   212     """Local utilities registrations table"""
   112     id = 'registrations_table'
   213 
   113     title = _("Utilities registrations")
   214     id = 'local_registrations_table'
       
   215     title = _("Local utilities registrations")
   114 
   216 
   115     data_attributes = {}
   217     data_attributes = {}
   116 
   218 
   117 
   219 
   118 @adapter_config(context=(ISite, IAdminLayer, RegistrationsTable), provides=IValues)
   220 @adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsTable), provides=IValues)
   119 class RegistrationsValuesAdapter(ContextRequestViewAdapter):
   221 class LocalRegistrationsValuesAdapter(ContextRequestViewAdapter):
   120     """Utilities values adapter"""
   222     """Local utilities values adapter"""
   121 
   223 
   122     @property
   224     @property
   123     def values(self):
   225     def values(self):
   124         return list(self.context.getSiteManager().registeredUtilities())
   226         return list(self.context.getSiteManager().registeredUtilities())
   125 
   227 
   126 
   228 
   127 @adapter_config(name='component', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
   229 @pagelet_config(name='local-registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
   128 class RegistrationsComponentColumn(GetAttrColumn):
       
   129     """Registrations component column"""
       
   130 
       
   131     _header = _("Component")
       
   132     weight = 1
       
   133 
       
   134     @property
       
   135     def header(self):
       
   136         return self.request.localizer.translate(self._header)
       
   137 
       
   138     def getValue(self, obj):
       
   139         return obj.component.__name__
       
   140 
       
   141 
       
   142 @adapter_config(name='interface', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
       
   143 class RegistrationsInterfaceColumn(GetAttrColumn):
       
   144     """Registrations interface column"""
       
   145 
       
   146     _header = _("Registered interface")
       
   147     weight = 5
       
   148 
       
   149     @property
       
   150     def header(self):
       
   151         return self.request.localizer.translate(self._header)
       
   152 
       
   153     def getValue(self, obj):
       
   154         return text_to_html(str(obj.provided))
       
   155 
       
   156 
       
   157 @adapter_config(name='name', context=(ISite, IAdminLayer, RegistrationsTable), provides=IColumn)
       
   158 class RegistrationsNameColumn(GetAttrColumn):
       
   159     """Registrations name column"""
       
   160 
       
   161     _header = _("Name")
       
   162     weight = 10
       
   163 
       
   164     @property
       
   165     def header(self):
       
   166         return self.request.localizer.translate(self._header)
       
   167 
       
   168     def getValue(self, obj):
       
   169         return obj.name or _('< no name >')
       
   170 
       
   171 
       
   172 @pagelet_config(name='registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
       
   173 @implementer(IInnerPage)
   230 @implementer(IInnerPage)
   174 class RegistrationsView(AdminView, ContainerView):
   231 class LocalRegistrationsView(AdminView, ContainerView):
   175     """Registrations view"""
   232     """Registrations view"""
   176 
   233 
   177     table_class = RegistrationsTable
   234     table_class = LocalRegistrationsTable
   178 
   235 
   179     def __init__(self, context, request):
   236     def __init__(self, context, request):
   180         super(RegistrationsView, self).__init__(context, request)
   237         super(LocalRegistrationsView, self).__init__(context, request)
   181 
   238 
   182 
   239 
   183 @adapter_config(context=(ISite, IAdminLayer, RegistrationsView), provides=IPageHeader)
   240 @adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IPageHeader)
   184 class RegistrationsHeaderAdapter(ContextRequestViewAdapter):
   241 class LocalRegistrationsHeaderAdapter(ContextRequestViewAdapter):
   185     """Registrations header adapter"""
   242     """Local registrations header adapter"""
   186 
   243 
   187     icon_class = 'fa fa-fw fa-codepen'
   244     icon_class = 'fa fa-fw fa-codepen'
   188     title = _("Control panel")
   245     title = _("Control panel")
   189     subtitle = _("Local utilities registry")
   246     subtitle = _("Local utilities registry")
   190 
   247 
   191 
   248 
   192 @adapter_config(context=(ISite, IAdminLayer, RegistrationsView), provides=IContentHelp)
   249 @adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IContentHelp)
   193 class RegistrationsHelpAdapter(ContentHelp):
   250 class LocalRegistrationsHelpAdapter(ContentHelp):
   194     """Registrations help adapter"""
   251     """Local registrations help adapter"""
   195 
   252 
   196     header = _("Local registry utilities")
   253     header = _("Local registry utilities")
   197     message = _("""A local registry is a registry defining utilities stored into
   254     message = _("""A local registry is a registry defining utilities stored into
   198 site's Object Database (ZODB).
   255 site's Object Database (ZODB).
   199 
   256 
   200 You can manage these utilities and modify their properties and site's behaviour without
   257 You can manage these utilities and modify their properties and site's behaviour without
   201 modifying the application.""")
   258 modifying the application.""")
   202     message_format = 'rest'
   259     message_format = 'rest'
       
   260 
       
   261 
       
   262 #
       
   263 # Global registrations views
       
   264 #
       
   265 
       
   266 @viewlet_config(name='global-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
       
   267                 permission='system.view', weight=2)
       
   268 class GlobalRegistrationsMenuItem(MenuItem):
       
   269     """Global registrations menu"""
       
   270 
       
   271     label = _("Global registrations")
       
   272     url = '#global-registrations.html'
       
   273 
       
   274 
       
   275 @implementer(IRegistrationsTable)
       
   276 class GlobalRegistrationsTable(BaseTable):
       
   277     """Utilities global registrations table"""
       
   278 
       
   279     id = 'global_registrations_table'
       
   280     title = _("Global utilities registrations")
       
   281 
       
   282     data_attributes = {}
       
   283 
       
   284 
       
   285 @adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsTable), provides=IValues)
       
   286 class GlobalRegistrationsValuesAdapter(ContextRequestViewAdapter):
       
   287     """Global utilities values adapter"""
       
   288 
       
   289     @property
       
   290     def values(self):
       
   291         return list(registered_utilities())
       
   292 
       
   293 
       
   294 @pagelet_config(name='global-registrations.html', context=ISite, layer=IPyAMSLayer, permission='system.view')
       
   295 @implementer(IInnerPage)
       
   296 class GlobalRegistrationsView(AdminView, ContainerView):
       
   297     """Global registrations view"""
       
   298 
       
   299     table_class = GlobalRegistrationsTable
       
   300 
       
   301     def __init__(self, context, request):
       
   302         super(GlobalRegistrationsView, self).__init__(context, request)
       
   303 
       
   304 
       
   305 @adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IPageHeader)
       
   306 class GlobalRegistrationsHeaderAdapter(ContextRequestViewAdapter):
       
   307     """Global registrations header adapter"""
       
   308 
       
   309     icon_class = 'fa fa-fw fa-codepen'
       
   310     title = _("Control panel")
       
   311     subtitle = _("Global utilities registry")
       
   312 
       
   313 
       
   314 @adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IContentHelp)
       
   315 class GlobalRegistrationsHelpAdapter(ContentHelp):
       
   316     """Global registrations help adapter"""
       
   317 
       
   318     header = _("Global registry utilities")
       
   319     message = _("""The global registry groups local utilities as well as utilities registered outside
       
   320 site's Object Database (ZODB).
       
   321 
       
   322 These utilities are declared statically (generally using include or ZCML directives) and can't be setup
       
   323 without modifying site configuration.""")
       
   324     message_format = 'rest'