annotate roundup/cgi/PageTemplates/Expressions.py @ 3882:46ef2a6fd79d

config option to limit nosy attachments based on size reworking of patch [SF#772323] from Philipp Gortan It tries to avoid reading the file contents just to get the file size but that was too hard for metakit backends. They don't inherit from blobfiles.FileStorage which makes it more challenging. Really that backend should be reworked to inherit from FileStorage. I'm not sure I like the default being sys.maxint. Maybe have 0 == unlimited? But what if someone really wanted to set it to 0 to mean "don't attach anything"?
author Justus Pendleton <jpend@users.sourceforge.net>
date Mon, 03 Sep 2007 17:14:09 +0000
parents 5f9e00836006
children 445e1bc8b1df
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
4 #
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
11 #
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
12 ##############################################################################
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
13 # Modified for Roundup:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 #
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
15 # 1. removed all Zope-specific code (doesn't even try to import that stuff now)
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
16 # 2. removed all Acquisition
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
17 # 3. removed blocking of leading-underscore URL components
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19 """Page Template Expression Engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21 Page Template-specific implementation of TALES, with handlers
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22 for Python expressions, string literals, and paths.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
23 """
1071
c08b3820edd1 Adhering to ZPL
Richard Jones <richard@users.sourceforge.net>
parents: 1065
diff changeset
24
2663
5f9e00836006 update comment
Richard Jones <richard@users.sourceforge.net>
parents: 2351
diff changeset
25 __version__='$Revision: 1.12 $'[11:-2]
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27 import re, sys
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 Undefined, Default, _parse_expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
30
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 _engine = None
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 def getEngine():
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 global _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 if _engine is None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 from PathIterator import Iterator
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37 _engine = Engine(Iterator)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 installHandlers(_engine)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 return _engine
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 def installHandlers(engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 reg = engine.registerType
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 pe = PathExpr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 for pt in ('standard', 'path', 'exists', 'nocall'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 reg(pt, pe)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 reg('string', StringExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47 reg('python', PythonExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 reg('not', NotExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 reg('defer', DeferExpr)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 from PythonExpr import getSecurityManager, PythonExpr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
52 guarded_getattr = getattr
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 from zExceptions import Unauthorized
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 except ImportError:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 Unauthorized = "Unauthorized"
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
57
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
58 def acquisition_security_filter(orig, inst, name, v, real_validate):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
59 if real_validate(orig, inst, name, v):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
60 return 1
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
61 raise Unauthorized, name
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
62
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 def call_with_ns(f, ns, arg=1):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 if arg==2:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 return f(None, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 return f(ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 class _SecureModuleImporter:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 """Simple version of the importer for use with trusted code."""
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 __allow_access_to_unprotected_subobjects__ = 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72 def __getitem__(self, module):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 __import__(module)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 return sys.modules[module]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
76 SecureModuleImporter = _SecureModuleImporter()
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
77
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 Undefs = (Undefined, AttributeError, KeyError,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79 TypeError, IndexError, Unauthorized)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81 def render(ob, ns):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 Calls the object, possibly a document template, or just returns it if
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84 not callable. (From DT_Util.py)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 """
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 if hasattr(ob, '__render_with_namespace__'):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 ob = call_with_ns(ob.__render_with_namespace__, ns)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 base = ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 if callable(base):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 if getattr(base, 'isDocTemp', 0):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 ob = call_with_ns(ob, ns, 2)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 ob = ob()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 except AttributeError, n:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 if str(n) != '__call__':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 raise
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 class SubPathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 def __init__(self, path):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
103 self._path = path = path.strip().split('/')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104 self._base = base = path.pop(0)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
105 if base and not _valid_name(base):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 raise CompilerError, 'Invalid variable name "%s"' % base
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 # Parse path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 self._dp = dp = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 for i in range(len(path)):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 e = path[i]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 if e[:1] == '?' and _valid_name(e[1:]):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 dp.append((i, e[1:]))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 dp.reverse()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 list=list, isinstance=isinstance, StringType=type('')):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 vars = econtext.vars
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118 path = self._path
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 if self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 path = list(path) # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 for i, varname in self._dp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 val = vars[varname]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 if isinstance(val, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 path[i] = val
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 # If the value isn't a string, assume it's a sequence
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 # of path names.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 path[i:i+1] = list(val)
1065
0f9aa62917bd much nicer error messages when there's a templating error
Richard Jones <richard@users.sourceforge.net>
parents: 1049
diff changeset
129 base = self._base
1136
7e193bbda38e added generic item editing
Richard Jones <richard@users.sourceforge.net>
parents: 1101
diff changeset
130 __traceback_info__ = 'path expression "%s"'%('/'.join(self._path))
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
131 if base == 'CONTEXTS' or not base:
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 ob = econtext.contexts
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 ob = vars[base]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 if isinstance(ob, DeferWrapper):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 ob = ob()
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 if path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 ob = restrictedTraverse(ob, path, getSecurityManager())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 class PathExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 self._name = name
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
145 self._hybrid = 0
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
146 paths = expr.split('|')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 self._subexprs = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 add = self._subexprs.append
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 for i in range(len(paths)):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
150 path = paths[i].lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 if _parse_expr(path):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 # This part is the start of another expression type,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 # so glue it back together and compile it.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
154 add(engine.compile(('|'.join(paths[i:]).lstrip())))
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
155 self._hybrid = 1
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 add(SubPathExpr(path)._eval)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159 def _exists(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 for expr in self._subexprs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 return 1
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 return 0
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169 def _eval(self, econtext,
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 isinstance=isinstance, StringType=type(''), render=render):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 for expr in self._subexprs[:-1]:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 # Try all but the last subexpression, skipping undefined ones.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 ob = expr(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 except Undefs:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 pass
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 else:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 break
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 else:
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
180 # On the last subexpression allow exceptions through, and
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
181 # don't autocall if the expression was not a subpath.
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 ob = self._subexprs[-1](econtext)
1233
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
183 if self._hybrid:
69bf0d381fd7 Zope Collector fixes.
Richard Jones <richard@users.sourceforge.net>
parents: 1181
diff changeset
184 return ob
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 if self._name == 'nocall' or isinstance(ob, StringType):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 return ob
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188 # Return the rendered object
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 return render(ob, econtext.vars)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 if self._name == 'exists':
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193 return self._exists(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 return self._eval(econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 return '%s expression %s' % (self._name, `self._s`)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200 return '%s:%s' % (self._name, `self._s`)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
202
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
203 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/[^}]*)*)}' % {'n': NAME_RE})
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 class StringExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 def __init__(self, name, expr, engine):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 self._s = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 if '%' in expr:
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
209 expr = expr.replace('%', '%%')
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 self._vars = vars = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 if '$' in expr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 parts = []
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
213 for exp in expr.split('$$'):
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 if parts: parts.append('$')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 while m is not None:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 parts.append(exp[:m.start()])
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 parts.append('%s')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 vars.append(PathExpr('path', m.group(1) or m.group(2),
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 engine))
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 exp = exp[m.end():]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 m = _interp.search(exp)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 if '$' in exp:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 raise CompilerError, (
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 '$ must be doubled or followed by a simple path')
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 parts.append(exp)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
227 expr = ''.join(parts)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 self._expr = expr
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
229
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 vvals = []
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 for var in self._vars:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 v = var(econtext)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
234 # I hope this isn't in use anymore.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
235 ## if isinstance(v, Exception):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
236 ## raise v
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 vvals.append(v)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 return self._expr % tuple(vvals)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 return 'string expression %s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 return 'string:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 class NotExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
248 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
250
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 def __call__(self, econtext):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
252 # We use the (not x) and 1 or 0 formulation to avoid changing
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
253 # the representation of the result in Python 2.3, where the
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
254 # result of "not" becomes an instance of bool.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
255 return (not econtext.evaluateBoolean(self._c)) and 1 or 0
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258 return 'not:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 class DeferWrapper:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261 def __init__(self, expr, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 self._expr = expr
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 self._econtext = econtext
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 def __str__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 return str(self())
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 def __call__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269 return self._expr(self._econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 class DeferExpr:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272 def __init__(self, name, expr, compiler):
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
273 self._s = expr = expr.lstrip()
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 self._c = compiler.compile(expr)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
275
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276 def __call__(self, econtext):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 return DeferWrapper(self._c, econtext)
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 def __repr__(self):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280 return 'defer:%s' % `self._s`
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
282 class TraversalError:
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
283 def __init__(self, path, name):
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
284 self.path = path
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
285 self.name = name
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
286
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
287
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
288
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
289 def restrictedTraverse(object, path, securityManager,
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
290 get=getattr, has=hasattr, N=None, M=[],
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
291 TupleType=type(()) ):
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
292
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
293 REQUEST = {'path': path}
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 path.reverse()
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
296 validate = securityManager.validate
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
297 __traceback_info__ = REQUEST
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
298 done = []
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 while path:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 name = path.pop()
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
301 __traceback_info__ = TraversalError(done, name)
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
302
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
303 if isinstance(name, TupleType):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
304 object = object(*name)
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
305 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
306
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
307 if not name:
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
308 # Skip directly to item access
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
309 o = object[name]
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
310 # Check access to the item.
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
311 if not validate(object, object, name, o):
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
312 raise Unauthorized, name
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
313 object = o
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
314 continue
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
315
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316 # Try an attribute.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
317 o = guarded_getattr(object, name, M)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
318 if o is M:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 # Try an item.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 try:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 # XXX maybe in Python 2.2 we can just check whether
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322 # the object has the attribute "__getitem__"
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 # instead of blindly catching exceptions.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324 o = object[name]
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 except AttributeError, exc:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 if str(exc).find('__getitem__') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 # XXX I think this only happens with
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 # ExtensionClass instances.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
331 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
332 raise
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 except TypeError, exc:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 if str(exc).find('unsubscriptable') >= 0:
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
335 # The object does not support the item interface.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 # Try to re-raise the original attribute error.
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
337 # XXX This is sooooo ugly.
2349
b43efe461b3e update PageTemplates to latest Zope codebase
Richard Jones <richard@users.sourceforge.net>
parents: 2005
diff changeset
338 guarded_getattr(object, name)
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
339 raise
2351
97fae0466d97 more ZPT porting tweaks
Richard Jones <richard@users.sourceforge.net>
parents: 2349
diff changeset
340 done.append((name, o))
1049
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
341 object = o
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
342
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343 return object

Roundup Issue Tracker: http://roundup-tracker.org/