src/pyams_skin/container.py
changeset 557 bca7a7e058a3
equal deleted inserted replaced
-1:000000000000 557:bca7a7e058a3
       
     1 #
       
     2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 from pyramid.exceptions import NotFound
       
    14 from pyramid.httpexceptions import HTTPInternalServerError, HTTPUnauthorized
       
    15 from pyramid.view import view_config
       
    16 from zope.container.interfaces import IContainer
       
    17 from zope.interface import implementer
       
    18 
       
    19 from pyams_form.security import get_edit_permission
       
    20 from pyams_skin.interfaces.container import IContainerBaseView
       
    21 from pyams_skin.layer import IPyAMSLayer
       
    22 from pyams_skin.table import BaseTable
       
    23 from pyams_template.template import template_config
       
    24 
       
    25 
       
    26 __docformat__ = 'restructuredtext'
       
    27 
       
    28 from pyams_utils import _
       
    29 
       
    30 
       
    31 @template_config(template='templates/container.pt', layer=IPyAMSLayer)
       
    32 @implementer(IContainerBaseView)
       
    33 class ContainerView(object):
       
    34     """Base container view"""
       
    35 
       
    36     table_class = BaseTable
       
    37 
       
    38     def __init__(self, context, request):
       
    39         super(ContainerView, self).__init__(context, request)
       
    40         self.table = self.table_class(context, request)
       
    41 
       
    42     def update(self):
       
    43         super(ContainerView, self).update()
       
    44         self.table.update()
       
    45 
       
    46 
       
    47 @view_config(name='delete-element.json', context=IContainer, request_type=IPyAMSLayer,
       
    48              renderer='json', xhr=True)
       
    49 def delete_container_element(request, container_factory=None, ignore_permission=False):
       
    50     """Delete container element
       
    51 
       
    52     This view is not strictly protected, but:
       
    53     - either the function is called from another protected view
       
    54     - either the view is checking edit permission from context adapter; if permission can't be found,
       
    55       an internal server error is raised!
       
    56     If the function is called from another unprotected view with 'ignore_permission=True',
       
    57     it's a configuration error.
       
    58 
       
    59     :param request: the current request
       
    60     :param container_factory: adapter interface or factory which may be used to access required
       
    61         container values
       
    62     :param ignore_permission: if False, container's edit permission is checked and an exception is
       
    63         raised if request doesn't have required permission; otherwise, no permission is checked.
       
    64         This argument should be set to True only when the function is called from another view
       
    65         which already checked required permission.
       
    66     """
       
    67     translate = request.localizer.translate
       
    68     # Get object name to be removed
       
    69     name = request.params.get('object_name')
       
    70     if not name:
       
    71         return {
       
    72             'status': 'message',
       
    73             'messagebox': {
       
    74                 'status': 'error',
       
    75                 'content': translate(_("No provided object_name argument!"))
       
    76             }
       
    77         }
       
    78     # Check container factory
       
    79     container = request.context
       
    80     if container_factory is not None:
       
    81         container = container_factory(container)
       
    82     # Check container
       
    83     if name not in container:
       
    84         return {
       
    85             'status': 'message',
       
    86             'messagebox': {
       
    87                 'status': 'error',
       
    88                 'content': translate(_("Given element name doesn't exist!"))
       
    89             }
       
    90         }
       
    91     # Check permission
       
    92     if not ignore_permission:
       
    93         context = container[name]
       
    94         permission = get_edit_permission(request, context)
       
    95         if permission is None:
       
    96             raise HTTPInternalServerError("Missing permission definition")
       
    97         elif not request.has_permission(permission, context):
       
    98             raise HTTPUnauthorized()
       
    99     # Delete element
       
   100     del container[name]
       
   101     return {'status': 'success'}
       
   102 
       
   103 
       
   104 def switch_element_attribute(request, interface, adapter_name='', attribute_name=''):
       
   105     """Sswitch container element attribute
       
   106 
       
   107     :param request: original browser request; request should contain a parameter called
       
   108         "object_name" which contains the name of the element which should be switched.
       
   109         A NotFound exception is raised if argument is not provided or if given argument
       
   110         doesn't match an existing element.
       
   111     :param interface: container interface to which request's context should be adapted
       
   112     :param adapter_name: name of the adapter to be used to get given interface
       
   113     :param attribute_name: name of the boolean attribute to be switched
       
   114     :return: a JSON object containing a boolean "attribute" property defining new element value.
       
   115     """
       
   116     context = request.context
       
   117     if interface.providedBy(context):
       
   118         container = context
       
   119     else:
       
   120         container = request.registry.queryAdapter(context, interface, name=adapter_name)
       
   121         if container is None:
       
   122             raise NotFound()
       
   123     object_name = request.params.get('object_name')
       
   124     if not object_name:
       
   125         raise NotFound()
       
   126     element = container.get(str(object_name))
       
   127     if element is None:
       
   128         raise NotFound()
       
   129     setattr(element, attribute_name, not getattr(element, attribute_name))
       
   130     return {
       
   131         'status': 'success',
       
   132         attribute_name: getattr(element, attribute_name)
       
   133     }
       
   134 
       
   135 
       
   136 def switch_element_visibility(request, interface, adapter_name=''):
       
   137     """Set container element visibility
       
   138 
       
   139     :param request: original browser request; request should contain a parameter called
       
   140         "object_name" which contains the name of the element which should be switched.
       
   141         A NotFound exception is raised if argument is not provided or if given argument
       
   142         doesn't match an existing element.
       
   143     :param interface: container interface to which request's context should be adapted
       
   144     :return: a JSON object containing a boolean "visible" property defining new element visibility.
       
   145     """
       
   146     return switch_element_attribute(request, interface, adapter_name, 'visible')