• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / Products.CMFCore / 6246931310

20 Sep 2023 09:54AM UTC coverage: 86.008% (-0.3%) from 86.266%
6246931310

Pull #131

github

mauritsvanrees
gha: don't need setup-python on 27 as we use the 27 container.
Pull Request #131: Make decodeFolderFilter and encodeFolderFilter non-public.

2466 of 3689 branches covered (0.0%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 1 file covered. (100.0%)

17297 of 19289 relevant lines covered (89.67%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.87
/src/Products/CMFCore/FSDTMLMethod.py
1
##############################################################################
2
#
3
# Copyright (c) 2001 Zope Foundation and Contributors.
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
""" Customizable DTML methods that come from the filesystem.
1✔
14
"""
15

16
import six
1✔
17
from six import get_unbound_function
1✔
18

19
from AccessControl.class_init import InitializeClass
1✔
20
from AccessControl.SecurityInfo import ClassSecurityInfo
1✔
21
from AccessControl.SecurityManagement import getSecurityManager
1✔
22
from App.special_dtml import HTML
1✔
23
from App.special_dtml import DTMLFile
1✔
24
from DocumentTemplate.security import RestrictedDTML
1✔
25
from OFS.DTMLMethod import DTMLMethod
1✔
26
from OFS.DTMLMethod import decapitate
1✔
27
from OFS.DTMLMethod import guess_content_type
1✔
28
from OFS.role import RoleManager
1✔
29
from ZPublisher.HTTPRequest import default_encoding
1✔
30

31
from .DirectoryView import registerFileExtension
1✔
32
from .DirectoryView import registerMetaType
1✔
33
from .FSObject import FSObject
1✔
34
from .permissions import FTPAccess
1✔
35
from .permissions import View
1✔
36
from .permissions import ViewManagementScreens
1✔
37
from .utils import HAS_ZSERVER
1✔
38
from .utils import _checkConditionalGET
1✔
39
from .utils import _dtmldir
1✔
40
from .utils import _setCacheHeaders
1✔
41

42

43
_marker = object()
1✔
44

45

46
class FSDTMLMethod(RestrictedDTML, RoleManager, FSObject, HTML):
1✔
47

48
    """FSDTMLMethods act like DTML methods but are not directly
49
    modifiable from the management interface.
50
    """
51

52
    meta_type = 'Filesystem DTML Method'
1✔
53
    zmi_icon = 'far fa-file-alt'
1✔
54
    _owner = None
1✔
55
    _proxy_roles = ()
1✔
56
    _cache_namespace_keys = ()
1✔
57
    _reading = 0
1✔
58

59
    manage_options = (
1✔
60
        {'label': 'Customize', 'action': 'manage_main'},
61
        {'label': 'View', 'action': ''},
62
        {'label': 'Proxy', 'action': 'manage_proxyForm'})
63

64
    security = ClassSecurityInfo()
1✔
65
    security.declareObjectProtected(View)
1✔
66

67
    security.declareProtected(ViewManagementScreens, 'manage_main')
1✔
68
    manage_main = DTMLFile('custdtml', _dtmldir)
1✔
69

70
    def __init__(self, id, filepath, fullname=None, properties=None):
1✔
71
        FSObject.__init__(self, id, filepath, fullname, properties)
1✔
72
        # Normally called via HTML.__init__ but we don't need the rest that
73
        # happens there.
74
        self.initvars(None, {})
1✔
75
        # Set a sane default encoding value if it was not already set
76
        if 'encoding' not in self.__dict__:
1✔
77
            self.encoding = default_encoding
1✔
78

79
    def _createZODBClone(self):
1✔
80
        """Create a ZODB (editable) equivalent of this object."""
81
        return DTMLMethod(self.read(), __name__=self.getId())
1✔
82

83
    def _readFile(self, reparse):
1✔
84
        """Read the data from the filesystem.
85
        """
86
        file = open(self._filepath, 'r')  # not 'rb', as this is a text file!
1✔
87
        try:
1✔
88
            data = file.read()
1✔
89
        finally:
90
            file.close()
1✔
91
        self.raw = data
1✔
92

93
        if reparse:
1✔
94
            self._reading = 1  # Avoid infinite recursion
1✔
95
            try:
1✔
96
                self.cook()
1✔
97
            finally:
98
                self._reading = 0
1✔
99

100
    # Hook up chances to reload in debug mode
101
    @security.private
1✔
102
    def read_raw(self):
1✔
103
        if not self._reading:
1✔
104
            self._updateFromFS()
1✔
105
        return HTML.read_raw(self)
1✔
106

107
    # The following is mainly taken from OFS/DTMLMethod.py
108

109
    index_html = None  # Prevent accidental acquisition
1✔
110

111
    # Documents masquerade as functions:
112
    __code__ = DTMLMethod.__code__
1✔
113

114
    default_content_type = 'text/html'
1✔
115

116
    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
1✔
117
        """Render the document given a client object, REQUEST mapping,
118
        Response, and key word arguments."""
119

120
        self._updateFromFS()
1✔
121

122
        kw['document_id'] = self.getId()
1✔
123
        kw['document_title'] = self.title
1✔
124
        kw['encoding'] = getattr(self, 'encoding') or None
1✔
125

126
        if client is not None:
1✔
127
            if _checkConditionalGET(self, kw):
1✔
128
                # caching policy manager hook
129
                _setCacheHeaders(self, {})
1✔
130
                return ''
1✔
131

132
        if not self._cache_namespace_keys:
1!
133
            data = self.ZCacheable_get(default=_marker)
1✔
134
            if data is not _marker:
1!
135
                # Return cached results.
136
                return data
×
137

138
        __traceback_info__ = self._filepath
1✔
139
        security = getSecurityManager()
1✔
140
        security.addContext(self)
1✔
141
        try:
1✔
142
            r = HTML.__call__(self, client, REQUEST, **kw)
1✔
143

144
            if client is None:
1✔
145
                # Called as subtemplate, so don't need error propagation!
146
                if RESPONSE is None:
1!
147
                    result = r
1✔
148
                else:
149
                    result = decapitate(r, RESPONSE)
×
150
                if not self._cache_namespace_keys:
1!
151
                    self.ZCacheable_set(result)
1✔
152
                return result
1✔
153

154
            if not isinstance(r, six.string_types) or RESPONSE is None:
1✔
155
                if not self._cache_namespace_keys:
1!
156
                    self.ZCacheable_set(r)
1✔
157
                return r
1✔
158

159
        finally:
160
            security.removeContext(self)
1✔
161

162
        headers = RESPONSE.headers
1✔
163
        if not ('content-type' in headers or 'Content-Type' in headers):
1✔
164
            if 'content_type' in self.__dict__:
1!
165
                c = self.content_type
×
166
            else:
167
                if six.PY2:
1!
168
                    c, _e = guess_content_type(self.getId(), r)
×
169
                else:
170
                    c, _e = guess_content_type(self.getId(), r.encode())
1✔
171

172
            RESPONSE.setHeader('Content-Type', c)
1✔
173
        if RESPONSE is not None:
1!
174
            # caching policy manager hook
175
            _setCacheHeaders(self, {})
1✔
176
        result = decapitate(r, RESPONSE)
1✔
177
        if not self._cache_namespace_keys:
1!
178
            self.ZCacheable_set(result)
1✔
179
        return result
1✔
180

181
    def getCacheNamespaceKeys(self):
1✔
182
        """
183
        Returns the cacheNamespaceKeys.
184
        """
185
        return self._cache_namespace_keys
×
186

187
    def setCacheNamespaceKeys(self, keys, REQUEST=None):
1✔
188
        """
189
        Sets the list of names that should be looked up in the
190
        namespace to provide a cache key.
191
        """
192
        ks = []
×
193
        for key in keys:
×
194
            key = str(key).strip()
×
195
            if key:
×
196
                ks.append(key)
×
197
        self._cache_namespace_keys = tuple(ks)
×
198
        if REQUEST is not None:
×
199
            return self.ZCacheable_manage(self, REQUEST)
×
200

201
    # Zope 2.3.x way:
202
    def validate(self, inst, parent, name, value, md=None):
1✔
203
        return getSecurityManager().validate(inst, parent, name, value)
1✔
204

205
    if HAS_ZSERVER:
1!
206
        security.declareProtected(FTPAccess, 'manage_FTPget')
×
207
        manage_FTPget = get_unbound_function(DTMLMethod.manage_FTPget)
×
208

209
    security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource')
1✔
210
    PrincipiaSearchSource = get_unbound_function(
1✔
211
                                DTMLMethod.PrincipiaSearchSource)
212

213
    security.declareProtected(ViewManagementScreens, 'document_src')
1✔
214
    document_src = get_unbound_function(DTMLMethod.document_src)
1✔
215

216
    security.declareProtected(ViewManagementScreens, 'manage_haveProxy')
1✔
217
    manage_haveProxy = get_unbound_function(DTMLMethod.manage_haveProxy)
1✔
218

219

220
InitializeClass(FSDTMLMethod)
1✔
221

222
registerFileExtension('dtml', FSDTMLMethod)
1✔
223
registerMetaType('DTML Method', FSDTMLMethod)
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc