|
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') |