Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
Zope
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
Zope
Commits
ca3753b2
Commit
ca3753b2
authored
Jun 19, 2010
by
Hanno Schlichting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved DocumentTemplate and TreeDisplay to their own distro
parent
13bc9b23
Changes
48
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
5 additions
and
7637 deletions
+5
-7637
buildout.cfg
buildout.cfg
+1
-0
setup.py
setup.py
+1
-7
src/DocumentTemplate/DT_HTML.py
src/DocumentTemplate/DT_HTML.py
+0
-315
src/DocumentTemplate/DT_If.py
src/DocumentTemplate/DT_If.py
+0
-139
src/DocumentTemplate/DT_In.py
src/DocumentTemplate/DT_In.py
+0
-898
src/DocumentTemplate/DT_InSV.py
src/DocumentTemplate/DT_InSV.py
+0
-407
src/DocumentTemplate/DT_Let.py
src/DocumentTemplate/DT_Let.py
+0
-111
src/DocumentTemplate/DT_Raise.py
src/DocumentTemplate/DT_Raise.py
+0
-75
src/DocumentTemplate/DT_Return.py
src/DocumentTemplate/DT_Return.py
+0
-39
src/DocumentTemplate/DT_String.py
src/DocumentTemplate/DT_String.py
+0
-536
src/DocumentTemplate/DT_Try.py
src/DocumentTemplate/DT_Try.py
+0
-214
src/DocumentTemplate/DT_UI.py
src/DocumentTemplate/DT_UI.py
+0
-91
src/DocumentTemplate/DT_Util.py
src/DocumentTemplate/DT_Util.py
+0
-437
src/DocumentTemplate/DT_Var.py
src/DocumentTemplate/DT_Var.py
+0
-505
src/DocumentTemplate/DT_With.py
src/DocumentTemplate/DT_With.py
+0
-81
src/DocumentTemplate/DTtestExpr.py
src/DocumentTemplate/DTtestExpr.py
+0
-55
src/DocumentTemplate/Let.stx
src/DocumentTemplate/Let.stx
+0
-36
src/DocumentTemplate/VSEval.py
src/DocumentTemplate/VSEval.py
+0
-9
src/DocumentTemplate/_DocumentTemplate.py
src/DocumentTemplate/_DocumentTemplate.py
+0
-114
src/DocumentTemplate/__init__.py
src/DocumentTemplate/__init__.py
+0
-25
src/DocumentTemplate/cDocumentTemplate.c
src/DocumentTemplate/cDocumentTemplate.c
+0
-1016
src/DocumentTemplate/html_quote.py
src/DocumentTemplate/html_quote.py
+0
-7
src/DocumentTemplate/pDocumentTemplate.py
src/DocumentTemplate/pDocumentTemplate.py
+0
-255
src/DocumentTemplate/permissions.py
src/DocumentTemplate/permissions.py
+0
-2
src/DocumentTemplate/security.py
src/DocumentTemplate/security.py
+0
-140
src/DocumentTemplate/sequence/SortEx.py
src/DocumentTemplate/sequence/SortEx.py
+0
-14
src/DocumentTemplate/sequence/__init__.py
src/DocumentTemplate/sequence/__init__.py
+0
-16
src/DocumentTemplate/sequence/tests/__init__.py
src/DocumentTemplate/sequence/tests/__init__.py
+0
-3
src/DocumentTemplate/sequence/tests/results.py
src/DocumentTemplate/sequence/tests/results.py
+0
-7
src/DocumentTemplate/sequence/tests/testSequence.py
src/DocumentTemplate/sequence/tests/testSequence.py
+0
-89
src/DocumentTemplate/sequence/tests/ztestlib.py
src/DocumentTemplate/sequence/tests/ztestlib.py
+0
-60
src/DocumentTemplate/tests/__init__.py
src/DocumentTemplate/tests/__init__.py
+0
-3
src/DocumentTemplate/tests/dealers.dtml
src/DocumentTemplate/tests/dealers.dtml
+0
-37
src/DocumentTemplate/tests/dealers.out
src/DocumentTemplate/tests/dealers.out
+0
-20
src/DocumentTemplate/tests/testDTML.py
src/DocumentTemplate/tests/testDTML.py
+0
-587
src/DocumentTemplate/tests/testDTMLUnicode.py
src/DocumentTemplate/tests/testDTMLUnicode.py
+0
-88
src/DocumentTemplate/tests/testSecurity.py
src/DocumentTemplate/tests/testSecurity.py
+0
-126
src/DocumentTemplate/tests/test_DT_Raise.py
src/DocumentTemplate/tests/test_DT_Raise.py
+0
-68
src/DocumentTemplate/tests/test_DT_Var.py
src/DocumentTemplate/tests/test_DT_Var.py
+0
-70
src/DocumentTemplate/tests/testustr.py
src/DocumentTemplate/tests/testustr.py
+0
-108
src/DocumentTemplate/ustr.py
src/DocumentTemplate/ustr.py
+0
-62
src/OFS/misc_.py
src/OFS/misc_.py
+2
-2
src/OFS/www/Minus_icon.gif
src/OFS/www/Minus_icon.gif
+0
-0
src/OFS/www/Plus_icon.gif
src/OFS/www/Plus_icon.gif
+0
-0
src/TreeDisplay/TreeTag.py
src/TreeDisplay/TreeTag.py
+0
-749
src/TreeDisplay/__init__.py
src/TreeDisplay/__init__.py
+0
-14
src/TreeDisplay/www/Blank_icon.gif
src/TreeDisplay/www/Blank_icon.gif
+0
-0
versions.cfg
versions.cfg
+1
-0
No files found.
buildout.cfg
View file @
ca3753b2
...
...
@@ -39,6 +39,7 @@ eggs =
AccessControl
Acquisition
DateTime
DocumentTemplate
ExtensionClass
Missing
MultiMapping
...
...
setup.py
View file @
ca3753b2
...
...
@@ -31,13 +31,6 @@ setup(name='Zope2',
package_dir
=
{
''
:
'src'
},
ext_modules
=
[
# DocumentTemplate
Extension
(
name
=
'DocumentTemplate.cDocumentTemplate'
,
include_dirs
=
[
'include'
,
'src'
],
sources
=
[
'src/DocumentTemplate/cDocumentTemplate.c'
],
depends
=
[
'include/ExtensionClass/ExtensionClass.h'
]),
# indexes
Extension
(
name
=
'Products.ZCTextIndex.stopper'
,
...
...
@@ -52,6 +45,7 @@ setup(name='Zope2',
'AccessControl'
,
'Acquisition'
,
'DateTime'
,
'DocumentTemplate'
,
'ExtensionClass'
,
'Missing'
,
'MultiMapping'
,
...
...
src/DocumentTemplate/DT_HTML.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""HTML formated DocumentTemplates
$Id$"""
import
re
from
DocumentTemplate.DT_String
import
String
,
FileMixin
from
DocumentTemplate.DT_Util
import
ParseError
,
str
class
dtml_re_class
:
""" This needs to be replaced before 2.4. It's a hackaround. """
def
search
(
self
,
text
,
start
=
0
,
name_match
=
re
.
compile
(
'[
\
000
- ]*[a-zA-Z]+[
\
000
- ]*'
).
match
,
end_match
=
re
.
compile
(
'[
\
000
- ]*(/|end)'
,
re
.
I
).
match
,
start_search
=
re
.
compile
(
'[<&]'
).
search
,
ent_name
=
re
.
compile
(
'[-a-zA-Z0-9_.]+'
).
match
,
):
while
1
:
mo
=
start_search
(
text
,
start
)
if
mo
is
None
:
return
None
s
=
mo
.
start
(
0
)
if
text
[
s
:
s
+
5
]
==
'<!--#'
:
n
=
s
+
5
e
=
text
.
find
(
'-->'
,
n
)
if
e
<
0
:
return
None
en
=
3
mo
=
end_match
(
text
,
n
)
if
mo
is
not
None
:
l
=
mo
.
end
(
0
)
-
mo
.
start
(
0
)
end
=
text
[
n
:
n
+
l
].
strip
()
n
=
n
+
l
else
:
end
=
''
elif
text
[
s
:
s
+
6
]
==
'<dtml-'
:
e
=
n
=
s
+
6
while
1
:
e
=
text
.
find
(
'>'
,
e
+
1
)
if
e
<
0
:
return
None
if
len
(
text
[
n
:
e
].
split
(
'"'
))
%
2
:
# check for even number of "s inside
break
en
=
1
end
=
''
elif
text
[
s
:
s
+
7
]
==
'</dtml-'
:
e
=
n
=
s
+
7
while
1
:
e
=
text
.
find
(
'>'
,
e
+
1
)
if
e
<
0
:
return
None
if
len
(
text
[
n
:
e
].
split
(
'"'
))
%
2
:
# check for even number of "s inside
break
en
=
1
end
=
'/'
else
:
if
text
[
s
:
s
+
5
]
==
'&dtml'
and
text
[
s
+
5
]
in
'.-'
:
n
=
s
+
6
e
=
text
.
find
(
';'
,
n
)
if
e
>=
0
:
args
=
text
[
n
:
e
]
l
=
len
(
args
)
mo
=
ent_name
(
args
)
if
mo
is
not
None
:
if
mo
.
end
(
0
)
-
mo
.
start
(
0
)
==
l
:
d
=
self
.
__dict__
if
text
[
s
+
5
]
==
'-'
:
d
[
1
]
=
d
[
'end'
]
=
''
d
[
2
]
=
d
[
'name'
]
=
'var'
d
[
0
]
=
text
[
s
:
e
+
1
]
d
[
3
]
=
d
[
'args'
]
=
args
+
' html_quote'
self
.
_start
=
s
return
self
else
:
nn
=
args
.
find
(
'-'
)
if
nn
>=
0
and
nn
<
l
-
1
:
d
[
1
]
=
d
[
'end'
]
=
''
d
[
2
]
=
d
[
'name'
]
=
'var'
d
[
0
]
=
text
[
s
:
e
+
1
]
args
=
args
[
nn
+
1
:]
+
' '
+
\
args
[:
nn
].
replace
(
'.'
,
' '
)
d
[
3
]
=
d
[
'args'
]
=
args
self
.
_start
=
s
return
self
start
=
s
+
1
continue
break
mo
=
name_match
(
text
,
n
)
if
mo
is
None
:
return
None
l
=
mo
.
end
(
0
)
-
mo
.
start
(
0
)
a
=
n
+
l
name
=
text
[
n
:
a
].
strip
()
args
=
text
[
a
:
e
].
strip
()
d
=
self
.
__dict__
d
[
0
]
=
text
[
s
:
e
+
en
]
d
[
1
]
=
d
[
'end'
]
=
end
d
[
2
]
=
d
[
'name'
]
=
name
d
[
3
]
=
d
[
'args'
]
=
args
self
.
_start
=
s
return
self
def
group
(
self
,
*
args
):
get
=
self
.
__dict__
.
get
if
len
(
args
)
==
1
:
return
get
(
args
[
0
])
return
tuple
(
map
(
get
,
args
))
def
start
(
self
,
*
args
):
return
self
.
_start
class
HTML
(
String
):
"""HTML Document Templates
HTML Document templates use HTML server-side-include syntax,
rather than Python format-string syntax. Here's a simple example:
<!--#in results-->
<!--#var name-->
<!--#/in-->
HTML document templates quote HTML tags in source when the
template is converted to a string. This is handy when templates
are inserted into HTML editing forms.
"""
tagre__roles__
=
()
def
tagre
(
self
):
return
dtml_re_class
()
parseTag__roles__
=
()
def
parseTag
(
self
,
match_ob
,
command
=
None
,
sargs
=
''
):
"""Parse a tag using an already matched re
Return: tag, args, command, coname
where: tag is the tag,
args is the tag
\
'
s argument string,
command is a corresponding command info structure if the
tag is a start tag, or None otherwise, and
coname is the name of a continue tag (e.g. else)
or None otherwise
"""
tag
,
end
,
name
,
args
=
match_ob
.
group
(
0
,
'end'
,
'name'
,
'args'
)
args
=
args
.
strip
()
if
end
:
if
not
command
or
name
!=
command
.
name
:
raise
ParseError
,
(
'unexpected end tag'
,
tag
)
return
tag
,
args
,
None
,
None
if
command
and
name
in
command
.
blockContinuations
:
if
name
==
'else'
and
args
:
# Waaaaaah! Have to special case else because of
# old else start tag usage. Waaaaaaah!
l
=
len
(
args
)
if
not
(
args
==
sargs
or
args
==
sargs
[:
l
]
and
sargs
[
l
:
l
+
1
]
in
'
\
t
\
n
'
):
return
tag
,
args
,
self
.
commands
[
name
],
None
return
tag
,
args
,
None
,
name
try
:
return
tag
,
args
,
self
.
commands
[
name
],
None
except
KeyError
:
raise
ParseError
,
(
'Unexpected tag'
,
tag
)
SubTemplate__roles__
=
()
def
SubTemplate
(
self
,
name
):
return
HTML
(
''
,
__name__
=
name
)
varExtra__roles__
=
()
def
varExtra
(
self
,
match_ob
):
return
's'
manage_edit__roles__
=
()
def
manage_edit
(
self
,
data
,
REQUEST
=
None
):
'edit a template'
self
.
munge
(
data
)
if
REQUEST
:
return
self
.
editConfirmation
(
self
,
REQUEST
)
quotedHTML__roles__
=
()
def
quotedHTML
(
self
,
text
=
None
,
character_entities
=
(
((
'&'
),
'&'
),
((
"<"
),
'<'
),
((
">"
),
'>'
),
((
'"'
),
'"'
))):
#"
if
text
is
None
:
text
=
self
.
read_raw
()
for
re
,
name
in
character_entities
:
if
text
.
find
(
re
)
>=
0
:
text
=
name
.
join
(
text
.
split
(
re
))
return
text
errQuote__roles__
=
()
errQuote
=
quotedHTML
def
__str__
(
self
):
return
self
.
quotedHTML
()
# these should probably all be deprecated.
management_interface__roles__
=
()
def
management_interface
(
self
):
'''Hook to allow public execution of management interface with
everything else private.'''
return
self
manage_editForm__roles__
=
()
def
manage_editForm
(
self
,
URL1
,
REQUEST
):
'''Display doc template editing form'''
#"
return
self
.
_manage_editForm
(
self
,
mapping
=
REQUEST
,
__str__
=
str
(
self
),
URL1
=
URL1
)
manage_editDocument__roles__
=
()
manage__roles__
=
()
manage_editDocument
=
manage
=
manage_editForm
class
HTMLDefault
(
HTML
):
'''
\
HTML document templates that edit themselves through copy.
This is to make a distinction from HTML objects that should edit
themselves in place.
'''
copy_class__roles__
=
()
copy_class
=
HTML
manage_edit__roles__
=
()
def
manage_edit
(
self
,
data
,
PARENTS
,
URL1
,
REQUEST
):
'edit a template'
newHTML
=
self
.
copy_class
(
data
,
self
.
globals
,
self
.
__name__
)
setattr
(
PARENTS
[
1
],
URL1
[
URL1
.
rfind
(
'/'
)
+
1
:],
newHTML
)
return
self
.
editConfirmation
(
self
,
REQUEST
)
class
HTMLFile
(
FileMixin
,
HTML
):
"""
\
HTML Document templates read from files.
If the object is pickled, the file name, rather
than the file contents is pickled. When the object is
unpickled, then the file will be re-read to obtain the string.
Note that the file will not be read until the document
template is used the first time.
"""
manage_default__roles__
=
()
def
manage_default
(
self
,
REQUEST
=
None
):
'Revert to factory defaults'
if
self
.
edited_source
:
self
.
edited_source
=
''
self
.
_v_cooked
=
self
.
cook
()
if
REQUEST
:
return
self
.
editConfirmation
(
self
,
REQUEST
)
manage_editForm__roles__
=
()
def
manage_editForm
(
self
,
URL1
,
REQUEST
):
'''Display doc template editing form'''
return
self
.
_manage_editForm
(
mapping
=
REQUEST
,
document_template_edit_width
=
self
.
document_template_edit_width
,
document_template_edit_header
=
self
.
document_template_edit_header
,
document_template_form_header
=
self
.
document_template_form_header
,
document_template_edit_footer
=
self
.
document_template_edit_footer
,
URL1
=
URL1
,
__str__
=
str
(
self
),
FactoryDefaultString
=
FactoryDefaultString
,
)
manage_editDocument__roles__
=
()
manage__roles__
=
()
manage_editDocument
=
manage
=
manage_editForm
manage_edit__roles__
=
()
def
manage_edit
(
self
,
data
,
PARENTS
=
[],
URL1
=
''
,
URL2
=
''
,
REQUEST
=
''
,
SUBMIT
=
''
):
'edit a template'
if
SUBMIT
==
FactoryDefaultString
:
return
self
.
manage_default
(
REQUEST
)
if
data
.
find
(
'
\
r
'
):
data
=
'
\
n
\
r
'
.
join
(
data
.
split
(
'
\
r
\
n
'
))
data
=
'
\
n
'
.
join
(
data
.
split
(
'
\
n
\
r
'
))
if
self
.
edited_source
:
self
.
edited_source
=
data
self
.
_v_cooked
=
self
.
cook
()
else
:
__traceback_info__
=
self
.
__class__
newHTML
=
self
.
__class__
()
newHTML
.
__setstate__
(
self
.
__getstate__
())
newHTML
.
edited_source
=
data
setattr
(
PARENTS
[
1
],
URL1
[
URL1
.
rfind
(
'/'
)
+
1
:],
newHTML
)
if
REQUEST
:
return
self
.
editConfirmation
(
self
,
REQUEST
)
src/DocumentTemplate/DT_If.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__
=
'''Conditional insertion
Conditional insertion is performed using 'if' and 'else'
commands.
To include text when an object is true using the EPFS
format, use::
%(if name)[
text
%(if name)]
To include text when an object is true using the HTML
format, use::
<!--#if name-->
text
<!--#/if name-->
where 'name' is the name bound to the object.
To include text when an object is false using the EPFS
format, use::
%(else name)[
text
%(else name)]
To include text when an object is false using the HTML
format, use::
<!--#else name-->
text
<!--#/else name-->
Finally to include text when an object is true and to
include different text when the object is false using the
EPFS format, use::
%(if name)[
true text
%(if name)]
%(else name)[
false text
%(else name)]
and to include text when an object is true and to
include different text when the object is false using the
HTML format, use::
<!--#if name-->
true text
<!--#else name-->
false text
<!--#/if name-->
Notes:
- if a variable is nor defined, it is considered to be false.
- A variable if only evaluated once in an 'if' tag. If the value
is used inside the tag, including in enclosed tags, the
variable is not reevaluated.
'''
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.19 $'
[
11
:
-
2
]
from
DocumentTemplate.DT_Util
import
ParseError
,
parse_params
,
name_param
,
str
class
If
:
blockContinuations
=
'else'
,
'elif'
name
=
'if'
elses
=
None
expr
=
''
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
)
name
,
expr
=
name_param
(
args
,
'if'
,
1
)
self
.
__name__
=
name
if
expr
is
None
:
cond
=
name
else
:
cond
=
expr
.
eval
sections
=
[
cond
,
section
.
blocks
]
if
blocks
[
-
1
][
0
]
==
'else'
:
tname
,
args
,
section
=
blocks
[
-
1
]
del
blocks
[
-
1
]
args
=
parse_params
(
args
,
name
=
''
)
if
args
:
ename
,
expr
=
name_param
(
args
,
'else'
,
1
)
if
ename
!=
name
:
raise
ParseError
,
(
'name in else does not match if'
,
'in'
)
elses
=
section
.
blocks
else
:
elses
=
None
for
tname
,
args
,
section
in
blocks
[
1
:]:
if
tname
==
'else'
:
raise
ParseError
,
(
'more than one else tag for a single if tag'
,
'in'
)
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
)
name
,
expr
=
name_param
(
args
,
'elif'
,
1
)
if
expr
is
None
:
cond
=
name
else
:
cond
=
expr
.
eval
sections
.
append
(
cond
)
sections
.
append
(
section
.
blocks
)
if
elses
is
not
None
:
sections
.
append
(
elses
)
self
.
simple_form
=
(
'i'
,)
+
tuple
(
sections
)
class
Unless
:
name
=
'unless'
blockContinuations
=
()
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
)
name
,
expr
=
name_param
(
args
,
'unless'
,
1
)
if
expr
is
None
:
cond
=
name
else
:
cond
=
expr
.
eval
self
.
simple_form
=
(
'i'
,
cond
,
None
,
section
.
blocks
)
class
Else
(
Unless
):
# The else tag is included for backward compatibility and is deprecated.
name
=
'else'
src/DocumentTemplate/DT_In.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
'''Sequence insertion
A sequence may be inserted using an 'in' command. The 'in'
command specifies the name of a sequence object and text to
be inserted for each element in the sequence.
The EPFS syntax for the in command is::
%(in name)[
text
%(in name)]
The HTML syntax for the in command is::
<!--#in name-->
text
<!--#/in name-->
See the example below that shows how 'if', 'else', and 'in' commands
may be combined to display a possibly empty list of objects.
The text included within an 'in' command will be refered to
as an 'in' block.
Synopsis
If the variable 'sequence' exists as a sequence, a simple case
of the 'in' tag is used as follows::
<!--#in sequence-->some markup<!--#/in-->
A more complete case is used as follows::
<!--#in sequence sort=age-->
<!--#var sequence-number-->) <!--#var age-->
<!--#/in-->
Attributes
sort -- Define the sort order for sequence items. Parameter to the
attribute is either a sort option, or list of sort options separated
by comma. Every sort option consists of variable name, optional
comparison function name (default is cmp) and optional sort order
(default is asc).
Examples: sort="date" or sort="date,time" or
sort="title/locale,date/cmp/desc". If you want to specify sort order,
you cannot omit the function; use cmp for standard comparison.
Few predefined comparison functions available: standard cmp,
nocase (ignore string case), strcoll (alias "locale"),
strcoll_nocase (alias "locale_nocase"). Locale functions are
available only if module locale is already imported (you started Zope
with -L locale).
sort_expr -- The "sort" attribute accepts only static list of
sort options. This calculated parameter allows you to calculate the
list of sort options on the fly.
sort_expr -- This allows an expression to control sort order.
reverse -- Reverse the sequence (may be combined with sort). Note
that this can cause a huge memory use in lazy activation instances.
reverse_expr -- This calculated parameter allows you to calculate the
need of reversing on the fly.
Within an 'in' block, variables are substituted from the
elements of the iteration unless the 'no_push_item' optional
is specified. The elements may be either instance or mapping
objects. In addition, the variables:
'sequence-item' -- The element.
'sequence-var-nnn' -- The value of a specific named attribute
of the item, where 'nnn' is the name. For example, to get
an items 'title' attribute, use 'sequence-var-title'. This
construct is most useful in an 'if' tag to test whether an
attribute is present, because the attribute lookup will be
extended to the full document template namespace.
'sequence-key' -- The key associated with the element in an
items list. See below.
'sequence-index' -- The index, starting from 0, of the
element within the sequence.
'sequence-number' -- The index, starting from 1, of the
element within the sequence.
'sequence-letter' -- The index, starting from 'a', of the
element within the sequence.
'sequence-Letter' -- The index, starting from 'A', of the
element within the sequence.
'sequence-roman' -- The index, starting from 'i', of the
element within the sequence.
'sequence-Roman' -- The index, starting from 'I', of the
element within the sequence.
'sequence-start' -- A variable that is true if the element
being displayed is the first of the displayed elements,
and false otherwise.
'sequence-end' -- A variable that is true if the element
being displayed is the last of the displayed elements,
and false otherwise.
are defined for each element.
Normally, 'in' blocks are used to iterate over sequences of
instances. If the optional parameter 'mapping' is specified
after the sequence name, then the elements of the sequence
will be treated as mapping objects.
An 'in' command may be used to iterate over a sequence of
dictionary items. If the elements of the iteration are
two-element tuples, then then the template code given in the
'in' block will be applied to the second element of each
tuple and may use a variable, 'sequence-key' to access the
first element in each tuple.
Batch sequence insertion
When displaying a large number of objects, it is sometimes
desirable to display just a sub-sequence of the data.
An 'in' command may have optional parameters,
as in::
<!--#in values start=start_var size=7-->
The parameter values may be either integer literals or
variable names.
Up to five parameters may be set:
'start' -- The number of the first element to be shown,
where elements are numbered from 1.
'end' -- The number of the last element to be shown,
where elements are numbered from 1.
'size' -- The desired number of elements to be shown at
once.
'orphan' -- The desired minimum number of objects to be
displayed. The default value for this
parameter is 0.
'overlap' -- The desired overlap between batches. The
default is no overlap.
Typically, only 'start' and 'size' will be specified.
When batch insertion is used, several additional variables are
defined for use within the sequence insertion text:
'sequence-query' -- The original query string given in a get
request with the form variable named in the 'start'
attribute removed. This is extremely useful when
building URLs to fetch another batch.
To see how this is used, consider the following example::
<!--#in search_results size=20 start=batch_start-->
... display rows
<!--#if sequence-end--> <!--#if next-sequence-->
<a href="&dtml-URL;/&dtml-sequence-query;batch_start=&dtml-next-sequence-start-number;">
(Next &dtml-next-sequence-size; results)
</a>
<!--#/if--> <!--#/if-->
<!--#/in-->
If the original URL is: 'foo/bar?x=1&y=2', then the
rendered text (after row data are displayed) will be::
<a href="foo/bar?x=1&y=2&batch_start=20">
(Next 20 results)
</a>
If the original URL is: 'foo/bar?batch_start=10&x=1&y=2',
then the rendered text (after row data are displayed)
will be::
<a href="foo/bar?x=1&y=2&batch_start=30">
(Next 20 results)
</a>
'sequence-step-start-index' -- The index, starting from 0,
of the start of the current batch.
'sequence-step-end-index' -- The index, starting from 0, of
the end of the current batch.
'sequence-step-size' -- The batch size used.
'previous-sequence' -- This variable will be true when the
first element is displayed and when the first element
displayed is not the first element in the sequence.
'previous-sequence-start-index' -- The index, starting from
0, of the start of the batch previous to the current
batch.
'previous-sequence-end-index' -- The index, starting from
0, of the end of the batch previous to the current
batch.
'previous-sequence-size' -- The size of the batch previous to
the current batch.
'previous-batches' -- A sequence of mapping objects
containing information about all of the batches prior
to the batch being displayed.
Each of these mapping objects include the following
variables:
batch-start-index -- The index, starting from
0, of the beginning of the batch.
batch-end-index -- The index, starting from
0, of the end of the batch.
batch-size -- The size of the batch.
'next-sequence' -- This variable will be true when the last
element is displayed and when the last element
displayed is not the last element in the sequence.
'next-sequence-start-index' -- The index, starting from
0, of the start of the batch after the current
batch.
'next-sequence-end-index' -- The index, starting from
0, of the end of the batch after the current
batch.
'next-sequence-size' -- The size of the batch after
the current batch.
'next-batches' -- A sequence of mapping objects
containing information about all of the batches after
the batch being displayed.
Each of these mapping objects include the following
variables:
batch-start-index -- The index, starting from
0, of the beginning of the batch.
batch-end-index -- The index, starting from
0, of the end of the batch.
batch-size -- The size of the batch.
For each of the variables listed above with names ending in
"-index", there are variables with names ending in "-number",
"-roman", "-Roman", "-letter", and "-Letter" that are indexed
from 1, "i", "I", "a", and "A", respectively. In addition,
for every one of these variables there are variables with
names ending in "-var-xxx", where "xxx" is an element
attribute name or key.
Summary statistics
When performing sequence insertion, special variables may be
used to obtain summary statistics. To obtain a summary
statistic for a variable, use the variable name:
'statistic-name', where 'statistic' is a statistic name and
'name' is the name of a data variable.
Currently supported statistic names are:
total -- The total of numeric values.
count -- The total number of non-missing values.
min -- The minimum of non-missing values.
max -- The maximum of non-missing values.
median -- The median of non-missing values.
mean -- The mean of numeric values values.
variance -- The variance of numeric values computed with a
degrees of freedom equal to the count - 1.
variance-n -- The variance of numeric values computed with a
degrees of freedom equal to the count.
standard-deviation -- The standard deviation of numeric values
computed with a degrees of freedom equal to the count - 1.
standard-deviation-n -- The standard deviation of numeric
values computed with a degrees of freedom equal to the count.
Missing values are either 'None' or the attribute 'Value'
of the module 'Missing', if present.
'else' continuation tag within in
An 'else' tag may be used as a continuation tag in the 'in' tag.
The source after the 'else' tag is inserted if:
- The sequence given to the 'in' tag is of zero length, or
- The 'previous' attribute was used and their are no
previous batches, or
- The 'next' attribute was used and their are no
next batches, or
'''
#'
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.62 $'
[
11
:
-
2
]
import
sys
import
re
from
DocumentTemplate.DT_Util
import
ParseError
,
parse_params
,
name_param
from
DocumentTemplate.DT_Util
import
str
,
join_unicode
from
DocumentTemplate.DT_Util
import
render_blocks
,
InstanceDict
from
DocumentTemplate.DT_Util
import
ValidationError
,
Eval
from
DocumentTemplate.DT_Util
import
simple_name
,
add_with_prefix
from
DocumentTemplate.DT_InSV
import
sequence_variables
,
opt
TupleType
=
tuple
StringTypes
=
(
str
,
unicode
)
class
InFactory
:
blockContinuations
=
(
'else'
,)
name
=
'in'
def
__call__
(
self
,
blocks
):
i
=
InClass
(
blocks
)
if
i
.
batch
:
return
i
.
renderwb
else
:
return
i
.
renderwob
In
=
InFactory
()
class
InClass
:
elses
=
None
expr
=
sort
=
batch
=
mapping
=
no_push_item
=
None
start_name_re
=
None
reverse
=
None
sort_expr
=
reverse_expr
=
None
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
args
=
parse_params
(
args
,
name
=
''
,
start
=
'1'
,
end
=
'-1'
,
size
=
'10'
,
orphan
=
'0'
,
overlap
=
'1'
,
mapping
=
1
,
no_push_item
=
1
,
skip_unauthorized
=
1
,
previous
=
1
,
next
=
1
,
expr
=
''
,
sort
=
''
,
reverse
=
1
,
sort_expr
=
''
,
reverse_expr
=
''
,
prefix
=
''
)
self
.
args
=
args
has_key
=
args
.
has_key
if
has_key
(
'sort'
):
self
.
sort
=
sort
=
args
[
'sort'
]
if
sort
==
'sequence-item'
:
self
.
sort
=
''
if
has_key
(
'sort_expr'
):
self
.
sort_expr
=
Eval
(
args
[
'sort_expr'
])
if
has_key
(
'reverse_expr'
):
self
.
reverse_expr
=
Eval
(
args
[
'reverse_expr'
])
if
has_key
(
'reverse'
):
self
.
reverse
=
args
[
'reverse'
]
if
has_key
(
'no_push_item'
):
self
.
no_push_item
=
args
[
'no_push_item'
]
if
has_key
(
'mapping'
):
self
.
mapping
=
args
[
'mapping'
]
for
n
in
'start'
,
'size'
,
'end'
:
if
has_key
(
n
):
self
.
batch
=
1
prefix
=
args
.
get
(
'prefix'
)
if
prefix
and
not
simple_name
(
prefix
):
raise
ParseError
,
_tm
(
'prefix is not a simple name'
,
'in'
)
for
n
in
'orphan'
,
'overlap'
,
'previous'
,
'next'
:
if
has_key
(
n
)
and
not
self
.
batch
:
raise
ParseError
,
(
"""
The %s attribute was used but neither of the
<code>start</code>, <code>end</code>, or <code>size</code>
attributes were used.
"""
%
n
,
'in'
)
if
has_key
(
'start'
):
v
=
args
[
'start'
]
if
type
(
v
)
==
type
(
''
):
try
:
int
(
v
)
except
:
self
.
start_name_re
=
re
.
compile
(
'&+'
+
''
.
join
([
"[%s]"
%
c
for
c
in
v
])
+
'=[0-9]+&+'
)
name
,
expr
=
name_param
(
args
,
'in'
,
1
)
if
expr
is
not
None
:
expr
=
expr
.
eval
self
.
__name__
,
self
.
expr
=
name
,
expr
self
.
section
=
section
.
blocks
if
len
(
blocks
)
>
1
:
if
len
(
blocks
)
!=
2
:
raise
ParseError
,
(
'too many else blocks'
,
'in'
)
tname
,
args
,
section
=
blocks
[
1
]
args
=
parse_params
(
args
,
name
=
''
)
if
args
:
ename
=
name_param
(
args
)
if
ename
!=
name
:
raise
ParseError
,
(
'name in else does not match in'
,
'in'
)
self
.
elses
=
section
.
blocks
def
renderwb
(
self
,
md
):
expr
=
self
.
expr
name
=
self
.
__name__
if
expr
is
None
:
sequence
=
md
[
name
]
cache
=
{
name
:
sequence
}
else
:
sequence
=
expr
(
md
)
cache
=
None
if
not
sequence
:
if
self
.
elses
:
return
render_blocks
(
self
.
elses
,
md
)
return
''
if
type
(
sequence
)
is
type
(
''
):
raise
ValueError
,
(
'Strings are not allowed as input to the in tag.'
)
section
=
self
.
section
params
=
self
.
args
mapping
=
self
.
mapping
no_push_item
=
self
.
no_push_item
if
self
.
sort_expr
is
not
None
:
self
.
sort
=
self
.
sort_expr
.
eval
(
md
)
sequence
=
self
.
sort_sequence
(
sequence
,
md
)
elif
self
.
sort
is
not
None
:
sequence
=
self
.
sort_sequence
(
sequence
,
md
)
if
self
.
reverse_expr
is
not
None
and
self
.
reverse_expr
.
eval
(
md
):
sequence
=
self
.
reverse_sequence
(
sequence
)
elif
self
.
reverse
is
not
None
:
sequence
=
self
.
reverse_sequence
(
sequence
)
next
=
previous
=
0
try
:
start
=
int_param
(
params
,
md
,
'start'
,
0
)
except
:
start
=
1
end
=
int_param
(
params
,
md
,
'end'
,
0
)
size
=
int_param
(
params
,
md
,
'size'
,
0
)
overlap
=
int_param
(
params
,
md
,
'overlap'
,
0
)
orphan
=
int_param
(
params
,
md
,
'orphan'
,
'0'
)
start
,
end
,
sz
=
opt
(
start
,
end
,
size
,
orphan
,
sequence
)
if
params
.
has_key
(
'next'
):
next
=
1
if
params
.
has_key
(
'previous'
):
previous
=
1
last
=
end
-
1
first
=
start
-
1
try
:
query_string
=
md
[
'QUERY_STRING'
]
except
:
query_string
=
''
prefix
=
params
.
get
(
'prefix'
)
vars
=
sequence_variables
(
sequence
,
'?'
+
query_string
,
self
.
start_name_re
,
prefix
)
kw
=
vars
.
data
pkw
=
add_with_prefix
(
kw
,
'sequence'
,
prefix
)
for
k
,
v
in
kw
.
items
():
pkw
[
k
]
=
v
pkw
[
'sequence-step-size'
]
=
sz
pkw
[
'sequence-step-overlap'
]
=
overlap
pkw
[
'sequence-step-start'
]
=
start
pkw
[
'sequence-step-end'
]
=
end
pkw
[
'sequence-step-start-index'
]
=
start
-
1
pkw
[
'sequence-step-end-index'
]
=
end
-
1
pkw
[
'sequence-step-orphan'
]
=
orphan
kw
[
'mapping'
]
=
mapping
push
=
md
.
_push
pop
=
md
.
_pop
render
=
render_blocks
if
cache
:
push
(
cache
)
push
(
vars
)
try
:
if
previous
:
if
first
>
0
:
pstart
,
pend
,
psize
=
opt
(
0
,
first
+
overlap
,
sz
,
orphan
,
sequence
)
pkw
[
'previous-sequence'
]
=
1
pkw
[
'previous-sequence-start-index'
]
=
pstart
-
1
pkw
[
'previous-sequence-end-index'
]
=
pend
-
1
pkw
[
'previous-sequence-size'
]
=
pend
+
1
-
pstart
result
=
render
(
section
,
md
)
elif
self
.
elses
:
result
=
render
(
self
.
elses
,
md
)
else
:
result
=
''
elif
next
:
try
:
# The following line is a sneaky way to test whether
# there are more items, without actually
# computing a length:
sequence
[
end
]
except
IndexError
:
if
self
.
elses
:
result
=
render
(
self
.
elses
,
md
)
else
:
result
=
''
else
:
pstart
,
pend
,
psize
=
opt
(
end
+
1
-
overlap
,
0
,
sz
,
orphan
,
sequence
)
pkw
[
'next-sequence'
]
=
1
pkw
[
'next-sequence-start-index'
]
=
pstart
-
1
pkw
[
'next-sequence-end-index'
]
=
pend
-
1
pkw
[
'next-sequence-size'
]
=
pend
+
1
-
pstart
result
=
render
(
section
,
md
)
else
:
result
=
[]
append
=
result
.
append
guarded_getitem
=
getattr
(
md
,
'guarded_getitem'
,
None
)
for
index
in
range
(
first
,
end
):
# preset
pkw
[
'previous-sequence'
]
=
0
pkw
[
'next-sequence'
]
=
0
# now more often defined then previously
#
if
index
==
first
or
index
==
last
:
# provide batching information
if
first
>
0
:
pstart
,
pend
,
psize
=
opt
(
0
,
first
+
overlap
,
sz
,
orphan
,
sequence
)
if
index
==
first
:
pkw
[
'previous-sequence'
]
=
1
pkw
[
'previous-sequence-start-index'
]
=
pstart
-
1
pkw
[
'previous-sequence-end-index'
]
=
pend
-
1
pkw
[
'previous-sequence-size'
]
=
pend
+
1
-
pstart
try
:
# The following line is a sneaky way to
# test whether there are more items,
# without actually computing a length:
sequence
[
end
]
pstart
,
pend
,
psize
=
opt
(
end
+
1
-
overlap
,
0
,
sz
,
orphan
,
sequence
)
if
index
==
last
:
pkw
[
'next-sequence'
]
=
1
pkw
[
'next-sequence-start-index'
]
=
pstart
-
1
pkw
[
'next-sequence-end-index'
]
=
pend
-
1
pkw
[
'next-sequence-size'
]
=
pend
+
1
-
pstart
except
:
pass
if
index
==
last
:
pkw
[
'sequence-end'
]
=
1
if
guarded_getitem
is
not
None
:
try
:
client
=
guarded_getitem
(
sequence
,
index
)
except
ValidationError
,
vv
:
if
(
params
.
has_key
(
'skip_unauthorized'
)
and
params
[
'skip_unauthorized'
]):
if
index
==
first
:
pkw
[
'sequence-start'
]
=
0
continue
raise
ValidationError
,
'(item %s): %s'
%
(
index
,
vv
),
sys
.
exc_info
()[
2
]
else
:
client
=
sequence
[
index
]
pkw
[
'sequence-index'
]
=
index
t
=
type
(
client
)
if
t
is
TupleType
and
len
(
client
)
==
2
:
client
=
client
[
1
]
if
no_push_item
:
pushed
=
0
elif
mapping
:
pushed
=
1
push
(
client
)
elif
t
in
StringTypes
:
pushed
=
0
else
:
pushed
=
1
push
(
InstanceDict
(
client
,
md
))
try
:
append
(
render
(
section
,
md
))
finally
:
if
pushed
:
pop
()
if
index
==
first
:
pkw
[
'sequence-start'
]
=
0
result
=
join_unicode
(
result
)
finally
:
if
cache
:
pop
()
pop
()
return
result
def
renderwob
(
self
,
md
):
"""RENDER WithOutBatch"""
expr
=
self
.
expr
name
=
self
.
__name__
if
expr
is
None
:
sequence
=
md
[
name
]
cache
=
{
name
:
sequence
}
else
:
sequence
=
expr
(
md
)
cache
=
None
if
not
sequence
:
if
self
.
elses
:
return
render_blocks
(
self
.
elses
,
md
)
return
''
if
type
(
sequence
)
is
type
(
''
):
raise
ValueError
,
(
'Strings are not allowed as input to the in tag.'
)
section
=
self
.
section
mapping
=
self
.
mapping
no_push_item
=
self
.
no_push_item
if
self
.
sort_expr
is
not
None
:
self
.
sort
=
self
.
sort_expr
.
eval
(
md
)
sequence
=
self
.
sort_sequence
(
sequence
,
md
)
elif
self
.
sort
is
not
None
:
sequence
=
self
.
sort_sequence
(
sequence
,
md
)
if
self
.
reverse_expr
is
not
None
and
self
.
reverse_expr
.
eval
(
md
):
sequence
=
self
.
reverse_sequence
(
sequence
)
elif
self
.
reverse
is
not
None
:
sequence
=
self
.
reverse_sequence
(
sequence
)
prefix
=
self
.
args
.
get
(
'prefix'
)
vars
=
sequence_variables
(
sequence
,
alt_prefix
=
prefix
)
kw
=
vars
.
data
pkw
=
add_with_prefix
(
kw
,
'sequence'
,
prefix
)
for
k
,
v
in
kw
.
items
():
pkw
[
k
]
=
v
kw
[
'mapping'
]
=
mapping
l
=
len
(
sequence
)
last
=
l
-
1
push
=
md
.
_push
pop
=
md
.
_pop
render
=
render_blocks
if
cache
:
push
(
cache
)
push
(
vars
)
try
:
result
=
[]
append
=
result
.
append
guarded_getitem
=
getattr
(
md
,
'guarded_getitem'
,
None
)
for
index
in
range
(
l
):
if
index
==
last
:
pkw
[
'sequence-end'
]
=
1
if
guarded_getitem
is
not
None
:
try
:
client
=
guarded_getitem
(
sequence
,
index
)
except
ValidationError
,
vv
:
if
(
self
.
args
.
has_key
(
'skip_unauthorized'
)
and
self
.
args
[
'skip_unauthorized'
]):
if
index
==
1
:
pkw
[
'sequence-start'
]
=
0
continue
raise
ValidationError
,
'(item %s): %s'
%
(
index
,
vv
),
sys
.
exc_info
()[
2
]
else
:
client
=
sequence
[
index
]
pkw
[
'sequence-index'
]
=
index
t
=
type
(
client
)
if
t
is
TupleType
and
len
(
client
)
==
2
:
client
=
client
[
1
]
if
no_push_item
:
pushed
=
0
elif
mapping
:
pushed
=
1
push
(
client
)
elif
t
in
StringTypes
:
pushed
=
0
else
:
pushed
=
1
push
(
InstanceDict
(
client
,
md
))
try
:
append
(
render
(
section
,
md
))
finally
:
if
pushed
:
pop
()
if
index
==
0
:
pkw
[
'sequence-start'
]
=
0
result
=
join_unicode
(
result
)
finally
:
if
cache
:
pop
()
pop
()
return
result
def
sort_sequence
(
self
,
sequence
,
md
):
# Modified with multiple sort fields by Ross Lazarus
# April 7 2000 rossl@med.usyd.edu.au
# eg <dtml-in "foo" sort="akey,anotherkey">
# Modified with advanced sort functions by
# Oleg Broytmann <phd@phd.pp.ru> 30 Mar 2001
# eg <dtml-in "foo" sort="akey/nocase,anotherkey/cmp/desc">
sort
=
self
.
sort
need_sortfunc
=
sort
.
find
(
'/'
)
>=
0
sortfields
=
sort
.
split
(
','
)
# multi sort = key1,key2
multsort
=
len
(
sortfields
)
>
1
# flag: is multiple sort
if
need_sortfunc
:
# prepare the list of functions and sort order multipliers
sf_list
=
make_sortfunctions
(
sortfields
,
md
)
# clean the mess a bit
if
multsort
:
# More than one sort key.
sortfields
=
map
(
lambda
x
:
x
[
0
],
sf_list
)
else
:
sort
=
sf_list
[
0
][
0
]
mapping
=
self
.
mapping
isort
=
not
sort
s
=
[]
for
client
in
sequence
:
k
=
None
if
type
(
client
)
==
TupleType
and
len
(
client
)
==
2
:
if
isort
:
k
=
client
[
0
]
v
=
client
[
1
]
else
:
if
isort
:
k
=
client
v
=
client
if
sort
:
if
multsort
:
# More than one sort key.
k
=
[]
for
sk
in
sortfields
:
if
mapping
:
akey
=
v
.
get
(
sk
)
else
:
akey
=
getattr
(
v
,
sk
,
None
)
if
not
basic_type
(
akey
):
try
:
akey
=
akey
()
except
:
pass
k
.
append
(
akey
)
else
:
# One sort key.
if
mapping
:
k
=
v
.
get
(
sort
)
else
:
k
=
getattr
(
v
,
sort
,
None
)
if
not
basic_type
(
type
(
k
)):
try
:
k
=
k
()
except
:
pass
s
.
append
((
k
,
client
))
if
need_sortfunc
:
by
=
SortBy
(
multsort
,
sf_list
)
s
.
sort
(
by
)
else
:
s
.
sort
()
sequence
=
[]
for
k
,
client
in
s
:
sequence
.
append
(
client
)
return
sequence
def
reverse_sequence
(
self
,
sequence
):
s
=
list
(
sequence
)
s
.
reverse
()
return
s
basic_type
=
{
type
(
''
):
1
,
type
(
0
):
1
,
type
(
0.0
):
1
,
type
(()):
1
,
type
([]):
1
,
type
(
None
)
:
1
}.
has_key
def
int_param
(
params
,
md
,
name
,
default
=
0
,
st
=
type
(
''
)):
try
:
v
=
params
[
name
]
except
:
v
=
default
if
v
:
try
:
v
=
int
(
v
)
except
:
v
=
md
[
v
]
if
type
(
v
)
is
st
:
v
=
int
(
v
)
return
v
# phd: Advanced sort support
def
nocase
(
str1
,
str2
):
return
cmp
(
str1
.
lower
(),
str2
.
lower
())
if
sys
.
modules
.
has_key
(
"locale"
):
# only if locale is already imported
from
locale
import
strcoll
def
strcoll_nocase
(
str1
,
str2
):
return
strcoll
(
str1
.
lower
(),
str2
.
lower
())
def
make_sortfunctions
(
sortfields
,
md
):
"""Accepts a list of sort fields; splits every field, finds comparison
function. Returns a list of 3-tuples (field, cmp_function, asc_multplier)"""
sf_list
=
[]
for
field
in
sortfields
:
f
=
field
.
split
(
'/'
)
l
=
len
(
f
)
if
l
==
1
:
f
.
append
(
"cmp"
)
f
.
append
(
"asc"
)
elif
l
==
2
:
f
.
append
(
"asc"
)
elif
l
==
3
:
pass
else
:
raise
SyntaxError
,
"sort option must contain no more than 2 slashes"
f_name
=
f
[
1
]
# predefined function?
if
f_name
==
"cmp"
:
func
=
cmp
# builtin
elif
f_name
==
"nocase"
:
func
=
nocase
elif
f_name
in
(
"locale"
,
"strcoll"
):
func
=
strcoll
elif
f_name
in
(
"locale_nocase"
,
"strcoll_nocase"
):
func
=
strcoll_nocase
else
:
# no - look it up in the namespace
func
=
md
.
getitem
(
f_name
,
0
)
sort_order
=
f
[
2
].
lower
()
if
sort_order
==
"asc"
:
multiplier
=
+
1
elif
sort_order
==
"desc"
:
multiplier
=
-
1
else
:
raise
SyntaxError
,
"sort oder must be either ASC or DESC"
sf_list
.
append
((
f
[
0
],
func
,
multiplier
))
return
sf_list
class
SortBy
:
def
__init__
(
self
,
multsort
,
sf_list
):
self
.
multsort
=
multsort
self
.
sf_list
=
sf_list
def
__call__
(
self
,
o1
,
o2
):
multsort
=
self
.
multsort
if
multsort
:
o1
=
o1
[
0
]
# if multsort - take the first element (key list)
o2
=
o2
[
0
]
sf_list
=
self
.
sf_list
l
=
len
(
sf_list
)
# assert that o1 and o2 are tuples of apropriate length
assert
len
(
o1
)
==
l
+
1
-
multsort
,
"%s, %d"
%
(
o1
,
l
+
multsort
)
assert
len
(
o2
)
==
l
+
1
-
multsort
,
"%s, %d"
%
(
o2
,
l
+
multsort
)
# now run through the list of functions in sf_list and
# compare every object in o1 and o2
for
i
in
range
(
l
):
# if multsort - we already extracted the key list
# if not multsort - i is 0, and the 0th element is the key
c1
,
c2
=
o1
[
i
],
o2
[
i
]
func
,
multiplier
=
sf_list
[
i
][
1
:
3
]
n
=
func
(
c1
,
c2
)
if
n
:
return
n
*
multiplier
# all functions returned 0 - identical sequences
return
0
src/DocumentTemplate/DT_InSV.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__
=
'''Sequence variables support
$Id$'''
__version__
=
'$Revision: 1.22 $'
[
11
:
-
2
]
from
math
import
sqrt
import
re
try
:
import
Missing
mv
=
Missing
.
Value
except
:
mv
=
None
TupleType
=
tuple
class
sequence_variables
:
alt_prefix
=
None
def
__init__
(
self
,
items
=
None
,
query_string
=
''
,
start_name_re
=
None
,
alt_prefix
=
''
):
self
.
items
=
items
self
.
query_string
=
query_string
self
.
start_name_re
=
start_name_re
if
alt_prefix
:
self
.
alt_prefix
=
alt_prefix
+
'_'
self
.
data
=
data
=
{
'previous-sequence'
:
0
,
'next-sequence'
:
0
,
'sequence-start'
:
1
,
'sequence-end'
:
0
,
}
def
__len__
(
self
):
return
1
def
number
(
self
,
index
):
return
index
+
1
def
even
(
self
,
index
):
return
index
%
2
==
0
def
odd
(
self
,
index
):
return
index
%
2
def
letter
(
self
,
index
):
return
chr
(
ord
(
'a'
)
+
index
)
def
Letter
(
self
,
index
):
return
chr
(
ord
(
'A'
)
+
index
)
def
key
(
self
,
index
):
return
self
.
items
[
index
][
0
]
def
item
(
self
,
index
,
tt
=
type
(())):
i
=
self
.
items
[
index
]
if
type
(
i
)
is
tt
and
len
(
i
)
==
2
:
return
i
[
1
]
return
i
def
roman
(
self
,
index
):
return
self
.
Roman
(
index
).
lower
()
def
Roman
(
self
,
num
):
# Force number to be an integer value
num
=
int
(
num
)
+
1
# Initialize roman as an empty string
roman
=
''
while
num
>=
1000
:
num
=
num
-
1000
roman
=
'%sM'
%
roman
while
num
>=
500
:
num
=
num
-
500
roman
=
'%sD'
%
roman
while
num
>=
100
:
num
=
num
-
100
roman
=
'%sC'
%
roman
while
num
>=
50
:
num
=
num
-
50
roman
=
'%sL'
%
roman
while
num
>=
10
:
num
=
num
-
10
roman
=
'%sX'
%
roman
while
num
>=
5
:
num
=
num
-
5
roman
=
'%sV'
%
roman
while
num
<
5
and
num
>=
1
:
num
=
num
-
1
roman
=
'%sI'
%
roman
# Replaces special cases in Roman Numerals
roman
=
roman
.
replace
(
'DCCCC'
,
'CM'
)
roman
=
roman
.
replace
(
'CCCC'
,
'CD'
)
roman
=
roman
.
replace
(
'LXXXX'
,
'XC'
)
roman
=
roman
.
replace
(
'XXXX'
,
'XL'
)
roman
=
roman
.
replace
(
'VIIII'
,
'IX'
)
roman
=
roman
.
replace
(
'IIII'
,
'IV'
)
return
roman
def
value
(
self
,
index
,
name
):
data
=
self
.
data
item
=
self
.
items
[
index
]
if
type
(
item
)
==
TupleType
and
len
(
item
)
==
2
:
item
=
item
[
1
]
if
data
[
'mapping'
]:
return
item
[
name
]
return
getattr
(
item
,
name
)
def
first
(
self
,
name
,
key
=
''
):
data
=
self
.
data
if
data
[
'sequence-start'
]:
return
1
index
=
data
[
'sequence-index'
]
return
self
.
value
(
index
,
name
)
!=
self
.
value
(
index
-
1
,
name
)
def
last
(
self
,
name
,
key
=
''
):
data
=
self
.
data
if
data
[
'sequence-end'
]:
return
1
index
=
data
[
'sequence-index'
]
return
self
.
value
(
index
,
name
)
!=
self
.
value
(
index
+
1
,
name
)
def
length
(
self
,
ignored
):
l
=
self
[
'sequence-length'
]
=
len
(
self
.
items
)
return
l
def
query
(
self
,
*
ignored
):
if
self
.
start_name_re
is
None
:
raise
KeyError
,
'sequence-query'
query_string
=
self
.
query_string
while
query_string
and
query_string
[:
1
]
in
'?&'
:
query_string
=
query_string
[
1
:]
while
query_string
[
-
1
:]
==
'&'
:
query_string
=
query_string
[:
-
1
]
if
query_string
:
query_string
=
'&%s&'
%
query_string
reg
=
self
.
start_name_re
if
type
(
reg
)
==
type
(
re
.
compile
(
r""
)):
mo
=
reg
.
search
(
query_string
)
if
mo
is
not
None
:
v
=
mo
.
group
(
0
)
l
=
mo
.
start
(
0
)
query_string
=
(
query_string
[:
l
]
+
query_string
[
l
+
len
(
v
)
-
1
:])
else
:
l
=
reg
.
search_group
(
query_string
,
(
0
,))
if
l
:
v
=
l
[
1
]
l
=
l
[
0
]
query_string
=
(
query_string
[:
l
]
+
query_string
[
l
+
len
(
v
)
-
1
:])
query_string
=
'?'
+
query_string
[
1
:]
else
:
query_string
=
'?'
self
[
'sequence-query'
]
=
query_string
return
query_string
statistic_names
=
(
'total'
,
'count'
,
'min'
,
'max'
,
'median'
,
'mean'
,
'variance'
,
'variance-n'
,
'standard-deviation'
,
'standard-deviation-n'
,
)
def
statistics
(
self
,
name
,
key
):
items
=
self
.
items
data
=
self
.
data
mapping
=
data
[
'mapping'
]
count
=
sum
=
sumsq
=
0
min
=
max
=
None
scount
=
smin
=
smax
=
None
values
=
[]
svalues
=
[]
for
item
in
items
:
try
:
if
mapping
:
item
=
item
[
name
]
else
:
try
:
item
=
getattr
(
item
,
name
)
except
:
if
name
!=
'item'
:
raise
try
:
if
item
is
mv
:
item
=
None
if
type
(
item
)
==
type
(
1
):
s
=
item
*
long
(
item
)
else
:
s
=
item
*
item
sum
=
sum
+
item
sumsq
=
sumsq
+
s
values
.
append
(
item
)
if
min
is
None
:
min
=
max
=
item
else
:
if
item
<
min
:
min
=
item
if
item
>
max
:
max
=
item
except
:
if
item
is
not
None
and
item
is
not
mv
:
if
smin
is
None
:
smin
=
smax
=
item
else
:
if
item
<
smin
:
smin
=
item
if
item
>
smax
:
smax
=
item
svalues
.
append
(
item
)
except
:
pass
# Initialize all stats to empty strings:
for
stat
in
self
.
statistic_names
:
data
[
'%s-%s'
%
(
stat
,
name
)]
=
''
count
=
len
(
values
)
try
:
# Numeric statistics
n
=
float
(
count
)
mean
=
sum
/
n
sumsq
=
sumsq
/
n
-
mean
*
mean
data
[
'mean-%s'
%
name
]
=
mean
data
[
'total-%s'
%
name
]
=
sum
data
[
'variance-n-%s'
%
name
]
=
sumsq
data
[
'standard-deviation-n-%s'
%
name
]
=
sqrt
(
sumsq
)
if
count
>
1
:
sumsq
=
sumsq
*
n
/
(
n
-
1
)
data
[
'variance-%s'
%
name
]
=
sumsq
data
[
'standard-deviation-%s'
%
name
]
=
sqrt
(
sumsq
)
else
:
data
[
'variance-%s'
%
name
]
=
''
data
[
'standard-deviation-%s'
%
name
]
=
''
except
:
if
min
is
None
:
min
,
max
,
values
=
smin
,
smax
,
svalues
else
:
if
smin
<
min
:
min
=
smin
if
smax
>
max
:
max
=
smax
values
=
values
+
svalues
count
=
len
(
values
)
data
[
'count-%s'
%
name
]
=
count
# data['_values']=values
if
min
is
not
None
:
data
[
'min-%s'
%
name
]
=
min
data
[
'max-%s'
%
name
]
=
max
values
.
sort
()
if
count
==
1
:
data
[
'median-%s'
%
name
]
=
min
else
:
n
=
count
+
1
if
n
/
2
*
2
==
n
:
data
[
'median-%s'
%
name
]
=
values
[
n
/
2
-
1
]
else
:
n
=
n
/
2
try
:
data
[
'median-%s'
%
name
]
=
(
values
[
n
]
+
values
[
n
-
1
])
/
2
except
:
try
:
data
[
'median-%s'
%
name
]
=
(
"between %s and %s"
%
(
values
[
n
],
values
[
n
-
1
]))
except
:
pass
return
data
[
key
]
def
next_batches
(
self
,
suffix
=
'batches'
,
key
=
''
):
if
suffix
!=
'batches'
:
raise
KeyError
,
key
data
=
self
.
data
sequence
=
self
.
items
try
:
if
not
data
[
'next-sequence'
]:
return
()
sz
=
data
[
'sequence-step-size'
]
start
=
data
[
'sequence-step-start'
]
end
=
data
[
'sequence-step-end'
]
l
=
len
(
sequence
)
orphan
=
data
[
'sequence-step-orphan'
]
overlap
=
data
[
'sequence-step-overlap'
]
except
:
AttributeError
,
'next-batches'
r
=
[]
while
end
<
l
:
start
,
end
,
spam
=
opt
(
end
+
1
-
overlap
,
0
,
sz
,
orphan
,
sequence
)
v
=
sequence_variables
(
self
.
items
,
self
.
query_string
,
self
.
start_name_re
)
d
=
v
.
data
d
[
'batch-start-index'
]
=
start
-
1
d
[
'batch-end-index'
]
=
end
-
1
d
[
'batch-size'
]
=
end
+
1
-
start
d
[
'mapping'
]
=
data
[
'mapping'
]
r
.
append
(
v
)
data
[
'next-batches'
]
=
r
return
r
def
previous_batches
(
self
,
suffix
=
'batches'
,
key
=
''
):
if
suffix
!=
'batches'
:
raise
KeyError
,
key
data
=
self
.
data
sequence
=
self
.
items
try
:
if
not
data
[
'previous-sequence'
]:
return
()
sz
=
data
[
'sequence-step-size'
]
start
=
data
[
'sequence-step-start'
]
end
=
data
[
'sequence-step-end'
]
l
=
len
(
sequence
)
orphan
=
data
[
'sequence-step-orphan'
]
overlap
=
data
[
'sequence-step-overlap'
]
except
:
AttributeError
,
'previous-batches'
r
=
[]
while
start
>
1
:
start
,
end
,
spam
=
opt
(
0
,
start
-
1
+
overlap
,
sz
,
orphan
,
sequence
)
v
=
sequence_variables
(
self
.
items
,
self
.
query_string
,
self
.
start_name_re
)
d
=
v
.
data
d
[
'batch-start-index'
]
=
start
-
1
d
[
'batch-end-index'
]
=
end
-
1
d
[
'batch-size'
]
=
end
+
1
-
start
d
[
'mapping'
]
=
data
[
'mapping'
]
r
.
append
(
v
)
r
.
reverse
()
data
[
'previous-batches'
]
=
r
return
r
special_prefixes
=
{
'first'
:
first
,
'last'
:
last
,
'previous'
:
previous_batches
,
'next'
:
next_batches
,
# These two are for backward compatability with a missfeature:
'sequence-index'
:
lambda
self
,
suffix
,
key
:
self
[
'sequence-'
+
suffix
],
'sequence-index-is'
:
lambda
self
,
suffix
,
key
:
self
[
'sequence-'
+
suffix
],
}
for
n
in
statistic_names
:
special_prefixes
[
n
]
=
statistics
def
__setitem__
(
self
,
key
,
value
):
self
.
data
[
key
]
=
value
if
self
.
alt_prefix
:
if
key
.
startswith
(
'sequence-'
):
key
=
key
[
9
:]
self
.
data
[
self
.
alt_prefix
+
key
]
=
value
def
__getitem__
(
self
,
key
,
special_prefixes
=
special_prefixes
,
special_prefix
=
special_prefixes
.
has_key
):
data
=
self
.
data
if
data
.
has_key
(
key
):
return
data
[
key
]
l
=
key
.
rfind
(
'-'
)
if
l
<
0
:
alt_prefix
=
self
.
alt_prefix
if
not
(
alt_prefix
and
key
.
startswith
(
alt_prefix
)):
raise
KeyError
,
key
suffix
=
key
[
len
(
alt_prefix
):].
replace
(
'_'
,
'-'
)
if
'-'
in
suffix
:
try
:
return
self
[
suffix
]
except
KeyError
:
pass
prefix
=
'sequence'
key
=
'sequence-'
+
suffix
else
:
suffix
=
key
[
l
+
1
:]
prefix
=
key
[:
l
]
if
hasattr
(
self
,
suffix
):
try
:
v
=
data
[
prefix
+
'-index'
]
except
:
pass
else
:
return
getattr
(
self
,
suffix
)(
v
)
if
special_prefix
(
prefix
):
return
special_prefixes
[
prefix
](
self
,
suffix
,
key
)
if
prefix
[
-
4
:]
==
'-var'
:
prefix
=
prefix
[:
-
4
]
try
:
return
self
.
value
(
data
[
prefix
+
'-index'
],
suffix
)
except
:
pass
if
key
==
'sequence-query'
:
return
self
.
query
()
raise
KeyError
,
key
def
opt
(
start
,
end
,
size
,
orphan
,
sequence
):
if
size
<
1
:
if
start
>
0
and
end
>
0
and
end
>=
start
:
size
=
end
+
1
-
start
else
:
size
=
7
if
start
>
0
:
try
:
sequence
[
start
-
1
]
except
:
start
=
len
(
sequence
)
# if start > l: start=l
if
end
>
0
:
if
end
<
start
:
end
=
start
else
:
end
=
start
+
size
-
1
try
:
sequence
[
end
+
orphan
-
1
]
except
:
end
=
len
(
sequence
)
# if l - end < orphan: end=l
elif
end
>
0
:
try
:
sequence
[
end
-
1
]
except
:
end
=
len
(
sequence
)
# if end > l: end=l
start
=
end
+
1
-
size
if
start
-
1
<
orphan
:
start
=
1
else
:
start
=
1
end
=
start
+
size
-
1
try
:
sequence
[
end
+
orphan
-
1
]
except
:
end
=
len
(
sequence
)
# if l - end < orphan: end=l
return
start
,
end
,
size
src/DocumentTemplate/DT_Let.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
''' The Let tag was contributed to Zope by and is copyright, 1999
Phillip J. Eby. Permission has been granted to release the Let tag
under the Zope Public License.
Let name=value...
The 'let' tag is used to bind variables to values within a block.
The text enclosed in the let tag is rendered using information
from the given variables or expressions.
For example::
<!--#let foofunc="foo()" my_bar=bar-->
foo() = <!--#var foofunc-->,
bar = <!--#var my_bar-->
<!--#/let-->
Notice that both 'name' and 'expr' style attributes may be used to
specify data. 'name' style attributes (e.g. my_bar=bar) will be
rendered as they are for var/with/in/etc. Quoted attributes will
be treated as Python expressions.
Variables are processed in sequence, so later assignments can
reference and/or overwrite the results of previous assignments,
as desired.
'''
import
re
from
DocumentTemplate.DT_Util
import
render_blocks
,
Eval
,
ParseError
from
DocumentTemplate.DT_Util
import
str
# Probably needed due to
# hysterical pickles.
class
Let
:
blockContinuations
=
()
name
=
'let'
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
self
.
__name__
=
args
self
.
section
=
section
.
blocks
self
.
args
=
args
=
parse_let_params
(
args
)
for
i
in
range
(
len
(
args
)):
name
,
expr
=
args
[
i
]
if
expr
[:
1
]
==
'"'
and
expr
[
-
1
:]
==
'"'
and
len
(
expr
)
>
1
:
# expr shorthand
expr
=
expr
[
1
:
-
1
]
try
:
args
[
i
]
=
name
,
Eval
(
expr
).
eval
except
SyntaxError
,
v
:
m
,(
huh
,
l
,
c
,
src
)
=
v
raise
ParseError
,
(
'<strong>Expression (Python) Syntax error</strong>:'
'
\
n
<pre>
\
n
%s
\
n
</pre>
\
n
'
%
v
[
0
],
'let'
)
def
render
(
self
,
md
):
d
=
{};
md
.
_push
(
d
)
try
:
for
name
,
expr
in
self
.
args
:
if
type
(
expr
)
is
type
(
''
):
d
[
name
]
=
md
[
expr
]
else
:
d
[
name
]
=
expr
(
md
)
return
render_blocks
(
self
.
section
,
md
)
finally
:
md
.
_pop
(
1
)
__call__
=
render
def
parse_let_params
(
text
,
result
=
None
,
tag
=
'let'
,
parmre
=
re
.
compile
(
'([
\
000
- ]*([^
\
000
- ="]+)=([^
\
000
- ="]+))'
),
qparmre
=
re
.
compile
(
'([
\
000
- ]*([^
\
000
- ="]+)="([^"]*)")'
),
**
parms
):
result
=
result
or
[]
mo
=
parmre
.
match
(
text
)
mo1
=
qparmre
.
match
(
text
)
if
mo
is
not
None
:
name
=
mo
.
group
(
2
)
value
=
mo
.
group
(
3
)
l
=
len
(
mo
.
group
(
1
))
elif
mo1
is
not
None
:
name
=
mo1
.
group
(
2
)
value
=
'"%s"'
%
mo1
.
group
(
3
)
l
=
len
(
mo1
.
group
(
1
))
else
:
if
not
text
or
not
text
.
strip
():
return
result
raise
ParseError
,
(
'invalid parameter: "%s"'
%
text
,
tag
)
result
.
append
((
name
,
value
))
text
=
text
[
l
:].
strip
()
if
text
:
return
parse_let_params
(
text
,
result
,
tag
,
**
parms
)
else
:
return
result
src/DocumentTemplate/DT_Raise.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
'''Raising exceptions
Errors can be raised from DTML using the 'raise' tag.
For example::
<!--#if expr="condition_that_tests_input"-->
<!--#raise type="Input Error"-->
The value you entered is not valid
<!--#/raise-->
<!--#/if-->
'''
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.13 $'
[
11
:
-
2
]
from
zExceptions
import
upgradeException
from
zExceptions
import
convertExceptionType
from
DocumentTemplate.DT_Util
import
name_param
from
DocumentTemplate.DT_Util
import
parse_params
from
DocumentTemplate.DT_Util
import
render_blocks
class
InvalidErrorTypeExpression
(
Exception
):
pass
class
Raise
:
blockContinuations
=
()
name
=
'raise'
expr
=
''
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
self
.
section
=
section
.
blocks
args
=
parse_params
(
args
,
type
=
''
,
expr
=
''
)
self
.
__name__
,
self
.
expr
=
name_param
(
args
,
'raise'
,
1
,
attr
=
'type'
)
def
render
(
self
,
md
):
expr
=
self
.
expr
if
expr
is
None
:
t
=
convertExceptionType
(
self
.
__name__
)
if
t
is
None
:
t
=
RuntimeError
else
:
try
:
t
=
expr
.
eval
(
md
)
except
:
t
=
convertExceptionType
(
self
.
__name__
)
if
t
is
None
:
t
=
InvalidErrorTypeExpression
try
:
v
=
render_blocks
(
self
.
section
,
md
)
except
:
v
=
'Invalid Error Value'
# String Exceptions are deprecated on Python 2.5 and
# plain won't work at all on Python 2.6. So try to upgrade it
# to a real exception.
t
,
v
=
upgradeException
(
t
,
v
)
raise
t
,
v
__call__
=
render
src/DocumentTemplate/DT_Return.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__version__
=
'$Revision: 1.9 $'
[
11
:
-
2
]
from
DocumentTemplate.DT_Util
import
parse_params
,
name_param
class
ReturnTag
:
name
=
'return'
expr
=
None
def
__init__
(
self
,
args
):
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
)
name
,
expr
=
name_param
(
args
,
'var'
,
1
)
self
.
__name__
=
name
self
.
expr
=
expr
def
render
(
self
,
md
):
if
self
.
expr
is
None
:
val
=
md
[
self
.
__name__
]
else
:
val
=
self
.
expr
.
eval
(
md
)
raise
DTReturn
(
val
)
__call__
=
render
class
DTReturn
:
def
__init__
(
self
,
v
):
self
.
v
=
v
src/DocumentTemplate/DT_String.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"$Id$"
import
os
import
thread
import
re
from
DocumentTemplate.DT_Util
import
ParseError
,
InstanceDict
from
DocumentTemplate.DT_Util
import
TemplateDict
,
render_blocks
,
str
from
DocumentTemplate.DT_Var
import
Var
,
Call
,
Comment
from
DocumentTemplate.DT_Return
import
ReturnTag
,
DTReturn
_marker
=
[]
# Create a new marker object.
class
String
:
"""Document templates defined from strings.
Document template strings use an extended form of python string
formatting. To insert a named value, simply include text of the
form: '%(name)x', where 'name' is the name of the value and 'x' is
a format specification, such as '12.2d'.
To intrduce a block such as an 'if' or an 'in' or a block continuation,
such as an 'else', use '[' as the format specification. To
terminate a block, ise ']' as the format specification, as in::
%(in results)[
%(name)s
%(in results)]
"""
isDocTemp
=
1
# Document Templates masquerade as functions:
class
func_code
:
pass
func_code
=
func_code
()
func_code
.
co_varnames
=
'self'
,
'REQUEST'
func_code
.
co_argcount
=
2
func_code
.
__roles__
=
()
func_defaults__roles__
=
()
func_defaults
=
()
errQuote__roles__
=
()
def
errQuote
(
self
,
s
):
return
s
parse_error__roles__
=
()
def
parse_error
(
self
,
mess
,
tag
,
text
,
start
):
raise
ParseError
,
"%s, for tag %s, on line %s of %s"
%
(
mess
,
self
.
errQuote
(
tag
),
len
(
text
[:
start
].
split
(
'
\
n
'
)),
self
.
errQuote
(
self
.
__name__
))
commands__roles__
=
()
commands
=
{
'var'
:
Var
,
'call'
:
Call
,
'in'
:
(
'in'
,
'DT_In'
,
'In'
),
'with'
:
(
'with'
,
'DT_With'
,
'With'
),
'if'
:
(
'if'
,
'DT_If'
,
'If'
),
'unless'
:
(
'unless'
,
'DT_If'
,
'Unless'
),
'else'
:
(
'else'
,
'DT_If'
,
'Else'
),
'comment'
:
Comment
,
'raise'
:
(
'raise'
,
'DT_Raise'
,
'Raise'
),
'try'
:
(
'try'
,
'DT_Try'
,
'Try'
),
'let'
:
(
'let'
,
'DT_Let'
,
'Let'
),
'return'
:
ReturnTag
,
}
SubTemplate__roles__
=
()
def
SubTemplate
(
self
,
name
):
return
String
(
''
,
__name__
=
name
)
tagre__roles__
=
()
def
tagre
(
self
):
return
re
.
compile
(
'%
\
\
('
# beginning
'(?P<name>[a-zA-Z0-9_/.-]+)'
# tag name
'('
'[
\
000
- ]+'
# space after tag name
'(?P<args>([^
\
\
)"]+("[^"]*")?)*)'
# arguments
')?'
'
\
\
)(?P<fmt>[0-9]*[.]?[0-9]*[a-z]|[]![])'
# end
,
re
.
I
)
_parseTag__roles__
=
()
def
_parseTag
(
self
,
match_ob
,
command
=
None
,
sargs
=
''
,
tt
=
type
(())):
tag
,
args
,
command
,
coname
=
self
.
parseTag
(
match_ob
,
command
,
sargs
)
if
type
(
command
)
is
tt
:
cname
,
module
,
name
=
command
d
=
{}
try
:
exec
'from %s import %s'
%
(
module
,
name
)
in
d
except
ImportError
:
exec
'from DocumentTemplate.%s import %s'
%
(
module
,
name
)
in
d
command
=
d
[
name
]
self
.
commands
[
cname
]
=
command
return
tag
,
args
,
command
,
coname
parseTag__roles__
=
()
def
parseTag
(
self
,
match_ob
,
command
=
None
,
sargs
=
''
):
"""Parse a tag using an already matched re
Return: tag, args, command, coname
where: tag is the tag,
args is the tag
\
'
s argument string,
command is a corresponding command info structure if the
tag is a start tag, or None otherwise, and
coname is the name of a continue tag (e.g. else)
or None otherwise
"""
tag
,
name
,
args
,
fmt
=
match_ob
.
group
(
0
,
'name'
,
'args'
,
'fmt'
)
args
=
args
and
args
.
strip
()
or
''
if
fmt
==
']'
:
if
not
command
or
name
!=
command
.
name
:
raise
ParseError
,
(
'unexpected end tag'
,
tag
)
return
tag
,
args
,
None
,
None
elif
fmt
==
'['
or
fmt
==
'!'
:
if
command
and
name
in
command
.
blockContinuations
:
if
name
==
'else'
and
args
:
# Waaaaaah! Have to special case else because of
# old else start tag usage. Waaaaaaah!
l
=
len
(
args
)
if
not
(
args
==
sargs
or
args
==
sargs
[:
l
]
and
sargs
[
l
:
l
+
1
]
in
'
\
t
\
n
'
):
return
tag
,
args
,
self
.
commands
[
name
],
None
return
tag
,
args
,
None
,
name
try
:
return
tag
,
args
,
self
.
commands
[
name
],
None
except
KeyError
:
raise
ParseError
,
(
'Unexpected tag'
,
tag
)
else
:
# Var command
args
=
args
and
(
"%s %s"
%
(
name
,
args
))
or
name
return
tag
,
args
,
Var
,
None
varExtra__roles__
=
()
def
varExtra
(
self
,
match_ob
):
return
match_ob
.
group
(
'fmt'
)
parse__roles__
=
()
def
parse
(
self
,
text
,
start
=
0
,
result
=
None
,
tagre
=
None
):
if
result
is
None
:
result
=
[]
if
tagre
is
None
:
tagre
=
self
.
tagre
()
mo
=
tagre
.
search
(
text
,
start
)
while
mo
:
l
=
mo
.
start
(
0
)
try
:
tag
,
args
,
command
,
coname
=
self
.
_parseTag
(
mo
)
except
ParseError
,
m
:
self
.
parse_error
(
m
[
0
],
m
[
1
],
text
,
l
)
s
=
text
[
start
:
l
]
if
s
:
result
.
append
(
s
)
start
=
l
+
len
(
tag
)
if
hasattr
(
command
,
'blockContinuations'
):
start
=
self
.
parse_block
(
text
,
start
,
result
,
tagre
,
tag
,
l
,
args
,
command
)
else
:
try
:
if
command
is
Var
:
r
=
command
(
args
,
self
.
varExtra
(
mo
))
else
:
r
=
command
(
args
)
if
hasattr
(
r
,
'simple_form'
):
r
=
r
.
simple_form
result
.
append
(
r
)
except
ParseError
,
m
:
self
.
parse_error
(
m
[
0
],
tag
,
text
,
l
)
mo
=
tagre
.
search
(
text
,
start
)
text
=
text
[
start
:]
if
text
:
result
.
append
(
text
)
return
result
skip_eol__roles__
=
()
def
skip_eol
(
self
,
text
,
start
,
eol
=
re
.
compile
(
'[
\
t
]*
\
n
'
)):
# if block open is followed by newline, then skip past newline
mo
=
eol
.
match
(
text
,
start
)
if
mo
is
not
None
:
start
=
start
+
mo
.
end
(
0
)
-
mo
.
start
(
0
)
return
start
parse_block__roles__
=
()
def
parse_block
(
self
,
text
,
start
,
result
,
tagre
,
stag
,
sloc
,
sargs
,
scommand
):
start
=
self
.
skip_eol
(
text
,
start
)
blocks
=
[]
tname
=
scommand
.
name
sname
=
stag
sstart
=
start
sa
=
sargs
while
1
:
mo
=
tagre
.
search
(
text
,
start
)
if
mo
is
None
:
self
.
parse_error
(
'No closing tag'
,
stag
,
text
,
sloc
)
l
=
mo
.
start
(
0
)
try
:
tag
,
args
,
command
,
coname
=
self
.
_parseTag
(
mo
,
scommand
,
sa
)
except
ParseError
,
m
:
self
.
parse_error
(
m
[
0
],
m
[
1
],
text
,
l
)
if
command
:
start
=
l
+
len
(
tag
)
if
hasattr
(
command
,
'blockContinuations'
):
# New open tag. Need to find closing tag.
start
=
self
.
parse_close
(
text
,
start
,
tagre
,
tag
,
l
,
command
,
args
)
else
:
# Either a continuation tag or an end tag
section
=
self
.
SubTemplate
(
sname
)
section
.
_v_blocks
=
section
.
blocks
=
self
.
parse
(
text
[:
l
],
sstart
)
section
.
_v_cooked
=
None
blocks
.
append
((
tname
,
sargs
,
section
))
start
=
self
.
skip_eol
(
text
,
l
+
len
(
tag
))
if
coname
:
tname
=
coname
sname
=
tag
sargs
=
args
sstart
=
start
else
:
try
:
r
=
scommand
(
blocks
)
if
hasattr
(
r
,
'simple_form'
):
r
=
r
.
simple_form
result
.
append
(
r
)
except
ParseError
,
m
:
self
.
parse_error
(
m
[
0
],
stag
,
text
,
l
)
return
start
parse_close__roles__
=
()
def
parse_close
(
self
,
text
,
start
,
tagre
,
stag
,
sloc
,
scommand
,
sa
):
while
1
:
mo
=
tagre
.
search
(
text
,
start
)
if
mo
is
None
:
self
.
parse_error
(
'No closing tag'
,
stag
,
text
,
sloc
)
l
=
mo
.
start
(
0
)
try
:
tag
,
args
,
command
,
coname
=
self
.
_parseTag
(
mo
,
scommand
,
sa
)
except
ParseError
,
m
:
self
.
parse_error
(
m
[
0
],
m
[
1
],
text
,
l
)
start
=
l
+
len
(
tag
)
if
command
:
if
hasattr
(
command
,
'blockContinuations'
):
# New open tag. Need to find closing tag.
start
=
self
.
parse_close
(
text
,
start
,
tagre
,
tag
,
l
,
command
,
args
)
elif
not
coname
:
return
start
shared_globals__roles__
=
()
shared_globals
=
{}
def
__init__
(
self
,
source_string
=
''
,
mapping
=
None
,
__name__
=
'<string>'
,
**
vars
):
"""
\
Create a document template from a string.
The optional parameter, 'mapping', may be used to provide a
mapping object containing defaults for values to be inserted.
"""
self
.
raw
=
source_string
self
.
initvars
(
mapping
,
vars
)
self
.
setName
(
__name__
)
def
name
(
self
):
return
self
.
__name__
id
=
name
setName__roles__
=
()
def
setName
(
self
,
v
):
self
.
__dict__
[
'__name__'
]
=
v
default__roles__
=
()
def
default
(
self
,
name
=
None
,
**
kw
):
"""
\
Change or query default values in a document template.
If a name is specified, the value of the named default value
before the operation is returned.
Keyword arguments are used to provide default values.
"""
if
name
:
name
=
self
.
globals
[
name
]
for
key
in
kw
.
keys
():
self
.
globals
[
key
]
=
kw
[
key
]
return
name
var__roles__
=
()
def
var
(
self
,
name
=
None
,
**
kw
):
"""
\
Change or query a variable in a document template.
If a name is specified, the value of the named variable before
the operation is returned.
Keyword arguments are used to provide variable values.
"""
if
name
:
name
=
self
.
_vars
[
name
]
for
key
in
kw
.
keys
():
self
.
_vars
[
key
]
=
kw
[
key
]
return
name
munge__roles__
=
()
def
munge
(
self
,
source_string
=
None
,
mapping
=
None
,
**
vars
):
"""
\
Change the text or default values for a document template.
"""
if
mapping
is
not
None
or
vars
:
self
.
initvars
(
mapping
,
vars
)
if
source_string
is
not
None
:
self
.
raw
=
source_string
self
.
cook
()
manage_edit__roles__
=
()
def
manage_edit
(
self
,
data
,
REQUEST
=
None
):
self
.
munge
(
data
)
read_raw__roles__
=
()
def
read_raw
(
self
,
raw
=
None
):
return
self
.
raw
read__roles__
=
()
def
read
(
self
,
raw
=
None
):
return
self
.
read_raw
()
cook__roles__
=
()
def
cook
(
self
,
cooklock
=
thread
.
allocate_lock
(),
):
cooklock
.
acquire
()
try
:
self
.
_v_blocks
=
self
.
parse
(
self
.
read
())
self
.
_v_cooked
=
None
finally
:
cooklock
.
release
()
initvars__roles__
=
()
def
initvars
(
self
,
globals
,
vars
):
if
globals
:
for
k
in
globals
.
keys
():
if
k
[:
1
]
!=
'_'
and
not
vars
.
has_key
(
k
):
vars
[
k
]
=
globals
[
k
]
self
.
globals
=
vars
self
.
_vars
=
{}
ZDocumentTemplate_beforeRender__roles__
=
()
def
ZDocumentTemplate_beforeRender
(
self
,
md
,
default
):
return
default
ZDocumentTemplate_afterRender__roles__
=
()
def
ZDocumentTemplate_afterRender
(
self
,
md
,
result
):
pass
def
__call__
(
self
,
client
=
None
,
mapping
=
{},
**
kw
):
'''
\
Generate a document from a document template.
The document will be generated by inserting values into the
format string specified when the document template was
created. Values are inserted using standard python named
string formats.
The optional argument 'client' is used to specify a object
containing values to be looked up. Values will be looked up
using getattr, so inheritence of values is supported. Note
that names beginning with '_' will not be looked up from the
client.
The optional argument, 'mapping' is used to specify a mapping
object containing values to be inserted.
Values to be inserted may also be specified using keyword
arguments.
Values will be inserted from one of several sources. The
sources, in the order in which they are consulted, are:
o Keyword arguments,
o The 'client' argument,
o The 'mapping' argument,
o The keyword arguments provided when the object was
created, and
o The 'mapping' argument provided when the template was
created.
'''
# print '============================================================'
# print '__called__'
# print self.raw
# print kw
# print client
# print mapping
# print '============================================================'
if
mapping
is
None
:
mapping
=
{}
if
hasattr
(
mapping
,
'taintWrapper'
):
mapping
=
mapping
.
taintWrapper
()
if
not
hasattr
(
self
,
'_v_cooked'
):
try
:
changed
=
self
.
__changed__
()
except
:
changed
=
1
self
.
cook
()
if
not
changed
:
self
.
__changed__
(
0
)
pushed
=
None
try
:
# Support Python 1.5.2, but work better in 2.1
if
(
mapping
.
__class__
is
TemplateDict
or
isinstance
(
mapping
,
TemplateDict
)):
pushed
=
0
except
:
pass
globals
=
self
.
globals
if
pushed
is
not
None
:
# We were passed a TemplateDict, so we must be a sub-template
md
=
mapping
push
=
md
.
_push
if
globals
:
push
(
self
.
globals
)
pushed
=
pushed
+
1
else
:
md
=
TemplateDict
()
push
=
md
.
_push
shared_globals
=
self
.
shared_globals
if
shared_globals
:
push
(
shared_globals
)
if
globals
:
push
(
globals
)
if
mapping
:
push
(
mapping
)
md
.
guarded_getattr
=
self
.
guarded_getattr
md
.
guarded_getitem
=
self
.
guarded_getitem
if
client
is
not
None
:
if
type
(
client
)
==
type
(()):
md
.
this
=
client
[
-
1
]
else
:
md
.
this
=
client
pushed
=
0
level
=
md
.
level
if
level
>
200
:
raise
SystemError
,
(
'infinite recursion in document template'
)
md
.
level
=
level
+
1
if
client
is
not
None
:
if
type
(
client
)
==
type
(()):
# if client is a tuple, it represents a "path" of clients
# which should be pushed onto the md in order.
for
ob
in
client
:
push
(
InstanceDict
(
ob
,
md
))
# Circ. Ref. 8-|
pushed
=
pushed
+
1
else
:
# otherwise its just a normal client object.
push
(
InstanceDict
(
client
,
md
))
# Circ. Ref. 8-|
pushed
=
pushed
+
1
if
self
.
_vars
:
push
(
self
.
_vars
)
pushed
=
pushed
+
1
if
kw
:
push
(
kw
)
pushed
=
pushed
+
1
try
:
value
=
self
.
ZDocumentTemplate_beforeRender
(
md
,
_marker
)
if
value
is
_marker
:
try
:
result
=
render_blocks
(
self
.
_v_blocks
,
md
)
except
DTReturn
,
v
:
result
=
v
.
v
self
.
ZDocumentTemplate_afterRender
(
md
,
result
)
return
result
else
:
return
value
finally
:
if
pushed
:
md
.
_pop
(
pushed
)
# Get rid of circular reference!
md
.
level
=
level
# Restore previous level
guarded_getattr
=
None
guarded_getitem
=
None
def
__str__
(
self
):
return
self
.
read
()
def
__getstate__
(
self
,
_special
=
(
'_v_'
,
'_p_'
)):
# Waaa, we need _v_ behavior but we may not subclass Persistent
d
=
{}
for
k
,
v
in
self
.
__dict__
.
items
():
if
k
[:
3
]
in
_special
:
continue
d
[
k
]
=
v
return
d
class
FileMixin
:
# Mix-in class to abstract certain file-related attributes
edited_source
=
''
def
__init__
(
self
,
file_name
=
''
,
mapping
=
None
,
__name__
=
''
,
**
vars
):
"""
\
Create a document template based on a named file.
The optional parameter, 'mapping', may be used to provide a
mapping object containing defaults for values to be inserted.
"""
self
.
raw
=
file_name
self
.
initvars
(
mapping
,
vars
)
self
.
setName
(
__name__
or
file_name
)
read_raw__roles__
=
()
def
read_raw
(
self
):
if
self
.
edited_source
:
return
self
.
edited_source
if
not
os
.
path
.
exists
(
self
.
raw
):
print
'file not found: %s'
%
self
.
raw
if
self
.
raw
:
return
open
(
self
.
raw
,
'r'
).
read
()
return
''
class
File
(
FileMixin
,
String
):
"""
\
Document templates read from files.
If the object is pickled, the file name, rather
than the file contents is pickled. When the object is
unpickled, then the file will be re-read to obtain the string.
Note that the file will not be read until the document
template is used the first time.
"""
manage_edit__roles__
=
()
def
manage_edit
(
self
,
data
):
raise
TypeError
,
'cannot edit files'
src/DocumentTemplate/DT_Try.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import
sys
,
traceback
from
cStringIO
import
StringIO
from
DocumentTemplate.DT_Util
import
ParseError
,
parse_params
,
render_blocks
from
DocumentTemplate.DT_Util
import
namespace
,
InstanceDict
from
DocumentTemplate.DT_Return
import
DTReturn
class
Try
:
"""Zope DTML Exception handling
usage:
<!--#try-->
<!--#except SomeError AnotherError-->
<!--#except YetAnotherError-->
<!--#except-->
<!--#else-->
<!--#/try-->
or:
<!--#try-->
<!--#finally-->
<!--#/try-->
The DTML try tag functions quite like Python's try command.
The contents of the try tag are rendered. If an exception is raised,
then control switches to the except blocks. The first except block to
match the type of the error raised is rendered. If an except block has
no name then it matches all raised errors.
The try tag understands class-based exceptions, as well as string-based
exceptions. Note: the 'raise' tag raises string-based exceptions.
Inside the except blocks information about the error is available via
three variables.
'error_type' -- This variable is the name of the exception caught.
'error_value' -- This is the caught exception's value.
'error_tb' -- This is a traceback for the caught exception.
The optional else block is rendered when no exception occurs in the
try block. Exceptions in the else block are not handled by the preceding
except blocks.
The try..finally form specifies a `cleanup` block, to be rendered even
when an exception occurs. Note that any rendered result is discarded if
an exception occurs in either the try or finally blocks. The finally block
is only of any use if you need to clean up something that will not be
cleaned up by the transaction abort code.
The finally block will always be called, wether there was an exception in
the try block or not, or wether or not you used a return tag in the try
block. Note that any output of the finally block is discarded if you use a
return tag in the try block.
If an exception occurs in the try block, and an exception occurs in the
finally block, or you use the return tag in that block, any information
about that first exception is lost. No information about the first
exception is available in the finally block. Also, if you use a return tag
in the try block, and an exception occurs in the finally block or you use
a return tag there as well, the result returned in the try block will be
lost.
Original version by Jordan B. Baker.
Try..finally and try..else implementation by Martijn Pieters.
"""
name
=
'try'
blockContinuations
=
'except'
,
'else'
,
'finally'
finallyBlock
=
None
elseBlock
=
None
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
self
.
args
=
parse_params
(
args
)
self
.
section
=
section
.
blocks
# Find out if this is a try..finally type
if
len
(
blocks
)
==
2
and
blocks
[
1
][
0
]
==
'finally'
:
self
.
finallyBlock
=
blocks
[
1
][
2
].
blocks
# This is a try [except]* [else] block.
else
:
# store handlers as tuples (name,block)
self
.
handlers
=
[]
defaultHandlerFound
=
0
for
tname
,
nargs
,
nsection
in
blocks
[
1
:]:
if
tname
==
'else'
:
if
not
self
.
elseBlock
is
None
:
raise
ParseError
,
(
'No more than one else block is allowed'
,
self
.
name
)
self
.
elseBlock
=
nsection
.
blocks
elif
tname
==
'finally'
:
raise
ParseError
,
(
'A try..finally combination cannot contain '
'any other else, except or finally blocks'
,
self
.
name
)
else
:
if
not
self
.
elseBlock
is
None
:
raise
ParseError
,
(
'The else block should be the last block '
'in a try tag'
,
self
.
name
)
for
errname
in
nargs
.
split
():
self
.
handlers
.
append
((
errname
,
nsection
.
blocks
))
if
nargs
.
strip
()
==
''
:
if
defaultHandlerFound
:
raise
ParseError
,
(
'Only one default exception handler '
'is allowed'
,
self
.
name
)
else
:
defaultHandlerFound
=
1
self
.
handlers
.
append
((
''
,
nsection
.
blocks
))
def
render
(
self
,
md
):
if
(
self
.
finallyBlock
is
None
):
return
self
.
render_try_except
(
md
)
else
:
return
self
.
render_try_finally
(
md
)
def
render_try_except
(
self
,
md
):
result
=
''
# first we try to render the first block
try
:
result
=
render_blocks
(
self
.
section
,
md
)
except
DTReturn
:
raise
except
:
# but an error occurs.. save the info.
t
,
v
=
sys
.
exc_info
()[:
2
]
if
type
(
t
)
==
type
(
''
):
errname
=
t
else
:
errname
=
t
.
__name__
handler
=
self
.
find_handler
(
t
)
if
handler
is
None
:
# we didn't find a handler, so reraise the error
raise
# found the handler block, now render it
try
:
f
=
StringIO
()
traceback
.
print_exc
(
100
,
f
)
error_tb
=
f
.
getvalue
()
ns
=
namespace
(
md
,
error_type
=
errname
,
error_value
=
v
,
error_tb
=
error_tb
)[
0
]
md
.
_push
(
InstanceDict
(
ns
,
md
))
return
render_blocks
(
handler
,
md
)
finally
:
md
.
_pop
(
1
)
else
:
# No errors have occured, render the optional else block
if
(
self
.
elseBlock
is
None
):
return
result
else
:
return
result
+
render_blocks
(
self
.
elseBlock
,
md
)
def
render_try_finally
(
self
,
md
):
result
=
''
# first try to render the first block
try
:
result
=
render_blocks
(
self
.
section
,
md
)
# Then handle finally block
finally
:
result
=
result
+
render_blocks
(
self
.
finallyBlock
,
md
)
return
result
def
find_handler
(
self
,
exception
):
"recursively search for a handler for a given exception"
if
type
(
exception
)
==
type
(
''
):
for
e
,
h
in
self
.
handlers
:
if
exception
==
e
or
e
==
''
:
return
h
else
:
return
None
for
e
,
h
in
self
.
handlers
:
if
e
==
exception
.
__name__
or
e
==
''
or
self
.
match_base
(
exception
,
e
):
return
h
return
None
def
match_base
(
self
,
exception
,
name
):
for
base
in
exception
.
__bases__
:
if
base
.
__name__
==
name
or
self
.
match_base
(
base
,
name
):
return
1
return
None
__call__
=
render
src/DocumentTemplate/DT_UI.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__
=
'''Machinery to support through-the-web editing
$Id$'''
__version__
=
'$Revision: 1.15 $'
[
11
:
-
2
]
from
DocumentTemplate.DT_HTML
import
HTML
FactoryDefaultString
=
"Factory Default"
HTML
.
document_template_edit_header
=
'<h2>Edit Document</h2>'
HTML
.
document_template_form_header
=
''
HTML
.
document_template_edit_footer
=
(
"""<FONT SIZE="-1">
<I><A HREF="http://www.zope.com">
© 2002 Zope Corporation</A></I></FONT>"""
)
HTML
.
_manage_editForm
=
HTML
(
"""<HTML>
<HEAD>
<TITLE>HTML Template Editor</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF">
<!--#var document_template_edit_header-->
<FORM name="editform" ACTION="&dtml-URL1;/manage_edit" METHOD="POST">
<!--#var document_template_form_header-->
Document template source:
<center>
<br>
<dtml-let cols="REQUEST.get('dtpref_cols', '100%')"
rows="REQUEST.get('dtpref_rows', '20')">
<dtml-if expr="cols[-1]=='%'">
<textarea name="data:text" style="width: &dtml-cols;;"
<dtml-else>
<textarea name="data:text" cols="&dtml-cols;"
</dtml-if>
rows="&dtml-rows;"><dtml-var __str__></textarea>
</dtml-let>
<br>
<INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Change">
<INPUT NAME=SUBMIT TYPE="RESET" VALUE="Reset">
<INPUT NAME="dt_edit_name" TYPE="HIDDEN"
VALUE="&dtml-URL1;">
<!--#if FactoryDefaultString-->
<INPUT NAME=SUBMIT TYPE="SUBMIT"
VALUE="&dtml-FactoryDefaultString;">
<!--#/if FactoryDefaultString-->
<INPUT NAME=SUBMIT TYPE="SUBMIT" VALUE="Cancel">
<!--#if HTTP_REFERER-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="&dtml-HTTP_REFERER;">
<!--#else HTTP_REFERER-->
<!--#if URL1-->
<INPUT NAME="CANCEL_ACTION" TYPE="HIDDEN"
VALUE="&dtml-URL1;">
<!--#/if URL1-->
<!--#/if HTTP_REFERER-->
</center>
</FORM>
<BR CLEAR="ALL">
<!--#var document_template_edit_footer-->
</BODY>
</HTML>"""
,)
HTML
.
editConfirmation
=
HTML
(
"""<html><head><title>Change Successful</title></head><body>
<!--#if CANCEL_ACTION-->
<form action="&dtml-CANCEL_ACTION;" method="POST">
<center>
<em>&dtml-dt_edit_name;</em><br>has been changed.<br><br>
<input type=submit name="SUBMIT" value="OK">
</center>
</form></body></html>
<!--#else CANCEL_ACTION-->
<center>
<em>&dtml-dt_edit_name;</em><br>has been changed.
</center>
<!--#/if CANCEL_ACTION-->"""
)
src/DocumentTemplate/DT_Util.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""DTML Utilities
$Id$
"""
import
re
import
string
from
types
import
BuiltinFunctionType
from
types
import
FunctionType
from
AccessControl.tainted
import
TaintedString
from
AccessControl.ZopeGuards
import
_safe_globals
from
RestrictedPython.Guards
import
safe_builtins
from
RestrictedPython.Utilities
import
utility_builtins
from
RestrictedPython.Eval
import
RestrictionCapableEval
# for import by other modules, dont remove!
from
DocumentTemplate.html_quote
import
html_quote
,
ustr
from
DocumentTemplate.cDocumentTemplate
import
InstanceDict
,
TemplateDict
from
DocumentTemplate.cDocumentTemplate
import
render_blocks
,
safe_callable
from
DocumentTemplate.cDocumentTemplate
import
join_unicode
from
DocumentTemplate
import
sequence
if
'test'
not
in
utility_builtins
:
from
RestrictedPython.Utilities
import
test
utility_builtins
[
'test'
]
=
test
test
=
utility_builtins
[
'test'
]
# for backwards compatibility, dont remove!
utility_builtins
[
'sequence'
]
=
sequence
safe_builtins
[
'sequence'
]
=
sequence
_safe_globals
[
'sequence'
]
=
sequence
LIMITED_BUILTINS
=
1
str
=
__builtins__
[
'str'
]
# Waaaaa, waaaaaaaa needed for pickling waaaaa
class
ParseError
(
Exception
):
"""Document Template Parse Error"""
from
zExceptions
import
Unauthorized
as
ValidationError
def
int_param
(
params
,
md
,
name
,
default
=
0
,
st
=
type
(
''
)):
v
=
params
.
get
(
name
,
default
)
if
v
:
try
:
v
=
int
(
v
)
except
:
v
=
md
[
v
]
if
isinstance
(
v
,
str
):
v
=
int
(
v
)
return
v
or
0
functype
=
type
(
int_param
)
class
NotBindable
:
# Used to prevent TemplateDict from trying to bind to functions.
def
__init__
(
self
,
f
):
self
.
__call__
=
f
for
name
,
f
in
safe_builtins
.
items
()
+
utility_builtins
.
items
():
if
type
(
f
)
is
functype
:
f
=
NotBindable
(
f
)
setattr
(
TemplateDict
,
name
,
f
)
if
LIMITED_BUILTINS
:
# Replace certain builtins with limited versions.
from
RestrictedPython.Limits
import
limited_builtins
for
name
,
f
in
limited_builtins
.
items
():
if
type
(
f
)
is
functype
:
f
=
NotBindable
(
f
)
setattr
(
TemplateDict
,
name
,
f
)
# Wrap the string module so it can deal with TaintedString strings.
class
StringModuleWrapper
:
def
__getattr__
(
self
,
key
):
attr
=
getattr
(
string
,
key
)
if
(
isinstance
(
attr
,
FunctionType
)
or
isinstance
(
attr
,
BuiltinFunctionType
)):
return
StringFunctionWrapper
(
attr
)
else
:
return
attr
class
StringFunctionWrapper
:
def
__init__
(
self
,
method
):
self
.
_method
=
method
def
__call__
(
self
,
*
args
,
**
kw
):
tainted
=
0
args
=
list
(
args
)
for
i
in
range
(
len
(
args
)):
if
isinstance
(
args
[
i
],
TaintedString
):
tainted
=
1
args
[
i
]
=
str
(
args
[
i
])
for
k
,
v
in
kw
.
items
():
if
isinstance
(
v
,
TaintedString
):
tainted
=
1
kw
[
k
]
=
str
(
v
)
args
=
tuple
(
args
)
retval
=
self
.
_method
(
*
args
,
**
kw
)
if
tainted
and
isinstance
(
retval
,
str
)
and
'<'
in
retval
:
retval
=
TaintedString
(
retval
)
return
retval
TemplateDict
.
string
=
StringModuleWrapper
()
TemplateDict
.
__allow_access_to_unprotected_subobjects__
=
1
# The functions below are meant to bind to the TemplateDict.
_marker
=
[]
# Create a new marker object.
def
careful_getattr
(
md
,
inst
,
name
,
default
=
_marker
):
get
=
md
.
guarded_getattr
if
get
is
None
:
get
=
getattr
try
:
return
get
(
inst
,
name
)
except
AttributeError
:
if
default
is
_marker
:
raise
return
default
def
careful_hasattr
(
md
,
inst
,
name
):
get
=
md
.
guarded_getattr
if
get
is
None
:
get
=
getattr
try
:
get
(
inst
,
name
)
except
(
AttributeError
,
ValidationError
,
KeyError
):
return
0
else
:
return
1
TemplateDict
.
getattr
=
careful_getattr
TemplateDict
.
hasattr
=
careful_hasattr
def
namespace
(
self
,
**
kw
):
"""Create a tuple consisting of a single instance whose attributes are
provided as keyword arguments."""
if
not
(
getattr
(
self
,
'__class__'
,
None
)
==
TemplateDict
or
isinstance
(
self
,
TemplateDict
)):
raise
TypeError
,
'''A call was made to DT_Util.namespace() with an
incorrect "self" argument. It could be caused by a product which
is not yet compatible with this version of Zope. The traceback
information may contain more details.)'''
return
self
(
**
kw
)
TemplateDict
.
namespace
=
namespace
def
render
(
self
,
v
):
"Render an object in the way done by the 'name' attribute"
if
hasattr
(
v
,
'__render_with_namespace__'
):
v
=
v
.
__render_with_namespace__
(
self
)
else
:
vbase
=
getattr
(
v
,
'aq_base'
,
v
)
if
safe_callable
(
vbase
):
if
getattr
(
vbase
,
'isDocTemp'
,
0
):
v
=
v
(
None
,
self
)
else
:
v
=
v
()
return
v
TemplateDict
.
render
=
render
class
Eval
(
RestrictionCapableEval
):
def
eval
(
self
,
md
):
gattr
=
getattr
(
md
,
'guarded_getattr'
,
None
)
if
gattr
is
not
None
:
gitem
=
getattr
(
md
,
'guarded_getitem'
,
None
)
self
.
prepRestrictedCode
()
code
=
self
.
rcode
d
=
{
'_'
:
md
,
'_vars'
:
md
,
'_getattr_'
:
gattr
,
'_getitem_'
:
gitem
,
'__builtins__'
:
None
}
else
:
self
.
prepUnrestrictedCode
()
code
=
self
.
ucode
d
=
{
'_'
:
md
,
'_vars'
:
md
}
d
.
update
(
self
.
globals
)
has_key
=
d
.
has_key
for
name
in
self
.
used
:
__traceback_info__
=
name
try
:
if
not
has_key
(
name
):
d
[
name
]
=
md
.
getitem
(
name
,
0
)
except
KeyError
:
# Swallow KeyErrors since the expression
# might not actually need the name. If it
# does need the name, a NameError will occur.
pass
return
eval
(
code
,
d
)
def
__call__
(
self
,
**
kw
):
# Never used?
md
=
TemplateDict
()
md
.
_push
(
kw
)
return
self
.
eval
(
md
)
simple_name
=
re
.
compile
(
'[a-z][a-z0-9_]*'
,
re
.
I
).
match
class
Add_with_prefix
:
def
__init__
(
self
,
map
,
defprefix
,
prefix
):
self
.
map
=
map
self
.
defprefix
=
defprefix
self
.
prefix
=
prefix
def
__setitem__
(
self
,
name
,
value
):
map
=
self
.
map
map
[
name
]
=
value
dp
=
self
.
defprefix
if
name
.
startswith
(
dp
+
'-'
):
map
[
self
.
prefix
+
name
[
len
(
dp
):].
replace
(
'-'
,
'_'
)]
=
value
else
:
map
[
'%s_%s'
%
(
self
.
prefix
,
name
)]
=
value
def
add_with_prefix
(
map
,
defprefix
,
prefix
):
if
not
prefix
:
return
map
return
Add_with_prefix
(
map
,
defprefix
,
prefix
)
def
name_param
(
params
,
tag
=
''
,
expr
=
0
,
attr
=
'name'
,
default_unnamed
=
1
):
used
=
params
.
has_key
__traceback_info__
=
params
,
tag
,
expr
,
attr
#if expr and used('expr') and used('') and not used(params['']):
# # Fix up something like: <!--#in expr="whatever" mapping-->
# params[params['']]=default_unnamed
# del params['']
if
used
(
''
):
v
=
params
[
''
]
if
v
[:
1
]
==
'"'
and
v
[
-
1
:]
==
'"'
and
len
(
v
)
>
1
:
# expr shorthand
if
used
(
attr
):
raise
ParseError
(
'%s and expr given'
%
attr
,
tag
)
if
expr
:
if
used
(
'expr'
):
raise
ParseError
(
'two exprs given'
,
tag
)
v
=
v
[
1
:
-
1
]
try
:
expr
=
Eval
(
v
)
except
SyntaxError
,
v
:
raise
ParseError
(
'<strong>Expression (Python) Syntax error</strong>:'
'
\
n
<pre>
\
n
%s
\
n
</pre>
\
n
'
%
v
[
0
],
tag
)
return
v
,
expr
else
:
raise
ParseError
(
'The "..." shorthand for expr was used in a tag '
'that doesn
\
'
t support expr attributes.'
,
tag
)
else
:
# name shorthand
if
used
(
attr
):
raise
ParseError
(
'Two %s values were given'
%
attr
,
tag
)
if
expr
:
if
used
(
'expr'
):
# raise 'Waaaaaa', 'waaa'
raise
ParseError
(
'%s and expr given'
%
attr
,
tag
)
return
params
[
''
],
None
return
params
[
''
]
elif
used
(
attr
):
if
expr
:
if
used
(
'expr'
):
raise
ParseError
(
'%s and expr given'
%
attr
,
tag
)
return
params
[
attr
],
None
return
params
[
attr
]
elif
expr
and
used
(
'expr'
):
name
=
params
[
'expr'
]
expr
=
Eval
(
name
)
return
name
,
expr
raise
ParseError
(
'No %s given'
%
attr
,
tag
)
Expr_doc
=
"""
Python expression support
Several document template tags, including 'var', 'in', 'if', 'else',
and 'elif' provide support for using Python expressions via an
'expr' tag attribute.
Expressions may be used where a simple variable value is
inadequate. For example, an expression might be used to test
whether a variable is greater than some amount::
<!--#if expr="age > 18"-->
or to transform some basic data::
<!--#var expr="phone[:3]"-->
Objects available in the document templates namespace may be used.
Subobjects of these objects may be used as well, although subobject
access is restricted by the optional validation method.
In addition, a special additional name, '_', is available. The '_'
variable provides access to the document template namespace as a
mapping object. This variable can be useful for accessing objects
in a document template namespace that have names that are not legal
Python variable names::
<!--#var expr="_['sequence-number']*5"-->
This variable also has attributes that provide access to standard
utility objects. These attributes include:
- The objects: 'None', 'abs', 'chr', 'divmod', 'float', 'hash',
'hex', 'int', 'len', 'max', 'min', 'oct', 'ord', 'pow',
'round', and 'str' from the standard Python builtin module.
- Special security-aware versions of 'getattr' and 'hasattr',
- The Python 'string', 'math', and 'random' modules, and
- A special function, 'test', that supports if-then expressions.
The 'test' function accepts any number of arguments. If the
first argument is true, then the second argument is returned,
otherwise if the third argument is true, then the fourth
argument is returned, and so on. If there is an odd number of
arguments, then the last argument is returned in the case that
none of the tested arguments is true, otherwise None is
returned.
For example, to convert a value to lower case::
<!--#var expr="_.string.lower(title)"-->
"""
ListType
=
type
([])
def
parse_params
(
text
,
result
=
None
,
tag
=
''
,
unparmre
=
re
.
compile
(
'([
\
000
- ]*([^
\
000
- ="]+))'
),
qunparmre
=
re
.
compile
(
'([
\
000
- ]*("[^"]*"))'
),
parmre
=
re
.
compile
(
'([
\
000
- ]*([^
\
000
- ="]+)=([^
\
000
- ="]+))'
),
qparmre
=
re
.
compile
(
'([
\
000
- ]*([^
\
000
- ="]+)="([^"]*)")'
),
**
parms
):
"""Parse tag parameters
The format of tag parameters consists of 1 or more parameter
specifications separated by whitespace. Each specification
consists of an unnamed and unquoted value, a valueless name, or a
name-value pair. A name-value pair consists of a name and a
quoted or unquoted value separated by an '='.
The input parameter, text, gives the text to be parsed. The
keyword parameters give valid parameter names and default values.
If a specification is not a name-value pair and it is not the
first specification and it is a
valid parameter name, then it is treated as a name-value pair with
a value as given in the keyword argument. Otherwise, if it is not
a name-value pair, it is treated as an unnamed value.
The data are parsed into a dictionary mapping names to values.
Unnamed values are mapped from the name '""'. Only one value may
be given for a name and there may be only one unnamed value. """
result
=
result
or
{}
# HACK - we precalculate all matches. Maybe we don't need them
# all. This should be fixed for performance issues
mo_p
=
parmre
.
match
(
text
)
mo_q
=
qparmre
.
match
(
text
)
mo_unp
=
unparmre
.
match
(
text
)
mo_unq
=
qunparmre
.
match
(
text
)
if
mo_p
:
name
=
mo_p
.
group
(
2
).
lower
()
value
=
mo_p
.
group
(
3
)
l
=
len
(
mo_p
.
group
(
1
))
elif
mo_q
:
name
=
mo_q
.
group
(
2
).
lower
()
value
=
mo_q
.
group
(
3
)
l
=
len
(
mo_q
.
group
(
1
))
elif
mo_unp
:
name
=
mo_unp
.
group
(
2
)
l
=
len
(
mo_unp
.
group
(
1
))
if
result
:
if
parms
.
has_key
(
name
):
if
parms
[
name
]
is
None
:
raise
ParseError
(
'Attribute %s requires a value'
%
name
,
tag
)
result
[
name
]
=
parms
[
name
]
else
:
raise
ParseError
(
'Invalid attribute name, "%s"'
%
name
,
tag
)
else
:
result
[
''
]
=
name
return
parse_params
(
text
[
l
:],
result
,
**
parms
)
elif
mo_unq
:
name
=
mo_unq
.
group
(
2
)
l
=
len
(
mo_unq
.
group
(
1
))
if
result
:
raise
ParseError
(
'Invalid attribute name, "%s"'
%
name
,
tag
)
else
:
result
[
''
]
=
name
return
parse_params
(
text
[
l
:],
result
,
**
parms
)
else
:
if
not
text
or
not
text
.
strip
():
return
result
raise
ParseError
(
'invalid parameter: "%s"'
%
text
,
tag
)
if
not
parms
.
has_key
(
name
):
raise
ParseError
(
'Invalid attribute name, "%s"'
%
name
,
tag
)
if
result
.
has_key
(
name
):
p
=
parms
[
name
]
if
type
(
p
)
is
not
ListType
or
p
:
raise
ParseError
(
'Duplicate values for attribute "%s"'
%
name
,
tag
)
result
[
name
]
=
value
text
=
text
[
l
:].
strip
()
if
text
:
return
parse_params
(
text
,
result
,
**
parms
)
else
:
return
result
src/DocumentTemplate/DT_Var.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Variable insertion parameters
When inserting variables, parameters may be specified to
control how the data will be formatted. In HTML source, the
'fmt' parameter is used to specify a C-style or custom format
to be used when inserting an object. In EPFS source, the 'fmt'
parameter is only used for custom formats, a C-style format is
specified after the closing parenthesis.
Custom formats
A custom format is used when outputing user-defined
objects. The value of a custom format is a method name to
be invoked on the object being inserted. The method should
return an object that, when converted to a string, yields
the desired text. For example, the DTML code::
<dtml-var date fmt=DayOfWeek>
Inserts the result of calling the method 'DayOfWeek' of the
object bound to the variable 'date', with no arguments.
In addition to object methods, serveral additional custom
formats are available:
'whole-dollars' -- Show a numeric value with a dollar symbol.
'dollars-and-cents' -- Show a numeric value with a dollar
symbol and two decimal places.
'collection-length' -- Get the length of a collection of objects.
Note that when using the EPFS source format, both a
C-style and a custom format may be provided. In this case,
the C-Style format is applied to the result of calling
the custom formatting method.
Null values and missing variables
In some applications, and especially in database applications,
data variables may alternate between "good" and "null" or
"missing" values. A format that is used for good values may be
inappropriate for null values. For this reason, the 'null'
parameter can be used to specify text to be used for null
values. Null values are defined as values that:
- Cannot be formatted with the specified format, and
- Are either the special Python value 'None' or
are false and yield an empty string when converted to
a string.
For example, when showing a monitary value retrieved from a
database that is either a number or a missing value, the
following variable insertion might be used::
<dtml-var cost fmt="$%.2d" null=
\
'
n/a
\
'
>
Missing values are providing for variables which are not
present in the name space, rather than raising an NameError,
you could do this:
<dtml-var cost missing=0>
and in this case, if cost was missing, it would be set to 0.
In the case where you want to deal with both at the same time,
you can use 'default':
<dtml-var description default=''>
In this case, it would use '' if the value was null or if the
variable was missing.
String manipulation
A number of special attributes are provided to transform the
value after formatting has been applied. These parameters
are supplied without arguments.
'lower' -- cause all upper-case letters to be converted to lower case.
'upper' -- cause all upper-case letters to be converted to lower case.
'capitalize' -- cause the first character of the inserted value
to be converted to upper case.
'spacify' -- cause underscores in the inserted value to be
converted to spaces.
'thousands_commas' -- cause commas to be inserted every three
digits to the left of a decimal point in values containing
numbers. For example, the value, "12000 widgets" becomes
"12,000 widgets".
'html_quote' -- convert characters that have special meaning
in HTML to HTML character entities.
'url_quote' -- convert characters that have special meaning
in URLS to HTML character entities using decimal values.
'url_quote_plus' -- like url_quote but also replace blank
space characters with '+'. This is needed for building
query strings in some cases.
'url_unquote' -- convert HTML character entities in strings
back to their real values.
'url_unquote_plus' -- like url_unquote, but also
replace '+' characters with spaces.
'sql_quote' -- Convert single quotes to pairs of single
quotes. This is needed to safely include values in
Standard Query Language (SQL) strings.
'newline_to_br' -- Convert newlines and carriage-return and
newline combinations to break tags.
'url' -- Get the absolute URL of the object by calling it
\
'
s
'absolute_url' method, if it has one.
Truncation
The attributes 'size' and 'etc' can be used to truncate long
strings. If the 'size' attribute is specified, the string to
be inserted is truncated at the given length. If a space
occurs in the second half of the truncated string, then the
string is further truncated to the right-most space. After
truncation, the value given for the 'etc' attribute is added to
the string. If the 'etc' attribute is not provided, then '...'
is used. For example, if the value of spam is
'"blah blah blah blah"', then the tag
'<dtml-var spam size=10>' inserts '"blah blah ..."'.
Evaluating expressions without rendering results
A 'call' tag is provided for evaluating named objects or expressions
without rendering the result.
"""
import
logging
import
re
import
string
import
sys
from
urllib
import
quote
,
quote_plus
,
unquote
,
unquote_plus
from
Acquisition
import
aq_base
from
AccessControl.tainted
import
TaintedString
from
zope.structuredtext.document
import
DocumentWithImages
# for import by other modules, dont remove!
from
DocumentTemplate.html_quote
import
html_quote
from
DocumentTemplate.DT_Util
import
parse_params
,
name_param
,
str
,
ustr
logger
=
logging
.
getLogger
(
'DocumentTemplate'
)
class
Var
:
name
=
'var'
expr
=
None
def
__init__
(
self
,
args
,
fmt
=
's'
):
if
args
[:
4
]
==
'var '
:
args
=
args
[
4
:]
args
=
parse_params
(
args
,
name
=
''
,
lower
=
1
,
upper
=
1
,
expr
=
''
,
capitalize
=
1
,
spacify
=
1
,
null
=
''
,
fmt
=
's'
,
size
=
0
,
etc
=
'...'
,
thousands_commas
=
1
,
html_quote
=
1
,
url_quote
=
1
,
sql_quote
=
1
,
url_quote_plus
=
1
,
url_unquote
=
1
,
url_unquote_plus
=
1
,
missing
=
''
,
newline_to_br
=
1
,
url
=
1
)
self
.
args
=
args
self
.
modifiers
=
tuple
(
map
(
lambda
t
:
t
[
1
],
filter
(
lambda
m
,
args
=
args
,
used
=
args
.
has_key
:
used
(
m
[
0
])
and
args
[
m
[
0
]],
modifiers
)))
name
,
expr
=
name_param
(
args
,
'var'
,
1
)
self
.
__name__
,
self
.
expr
=
name
,
expr
self
.
fmt
=
fmt
if
len
(
args
)
==
1
and
fmt
==
's'
:
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
(
'v'
,
expr
)
elif
len
(
args
)
==
2
and
fmt
==
's'
and
args
.
has_key
(
'html_quote'
):
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
(
'v'
,
expr
,
'h'
)
def
render
(
self
,
md
):
args
=
self
.
args
have_arg
=
args
.
has_key
name
=
self
.
__name__
val
=
self
.
expr
if
val
is
None
:
if
md
.
has_key
(
name
):
if
have_arg
(
'url'
):
val
=
md
.
getitem
(
name
,
0
)
val
=
val
.
absolute_url
()
else
:
val
=
md
[
name
]
else
:
if
have_arg
(
'missing'
):
return
args
[
'missing'
]
else
:
raise
KeyError
,
name
else
:
val
=
val
.
eval
(
md
)
if
have_arg
(
'url'
):
val
=
val
.
absolute_url
()
__traceback_info__
=
name
,
val
,
args
if
have_arg
(
'null'
)
and
not
val
and
val
!=
0
:
# check for null (false but not zero, including None, [], '')
return
args
[
'null'
]
# handle special formats defined using fmt= first
if
have_arg
(
'fmt'
):
_get
=
getattr
(
md
,
'guarded_getattr'
,
None
)
if
_get
is
None
:
_get
=
getattr
fmt
=
args
[
'fmt'
]
if
have_arg
(
'null'
)
and
not
val
and
val
!=
0
:
try
:
if
hasattr
(
val
,
fmt
):
val
=
_get
(
val
,
fmt
)()
elif
special_formats
.
has_key
(
fmt
):
if
fmt
==
'html-quote'
and
\
isinstance
(
val
,
TaintedString
):
# TaintedStrings will be quoted by default, don't
# double quote.
pass
else
:
val
=
special_formats
[
fmt
](
val
,
name
,
md
)
elif
fmt
==
''
:
val
=
''
else
:
if
isinstance
(
val
,
TaintedString
):
val
=
TaintedString
(
fmt
%
val
)
else
:
val
=
fmt
%
val
except
:
t
,
v
=
sys
.
exc_type
,
sys
.
exc_value
if
hasattr
(
sys
,
'exc_info'
):
t
,
v
=
sys
.
exc_info
()[:
2
]
if
val
is
None
or
not
str
(
val
):
return
args
[
'null'
]
raise
t
,
v
else
:
# We duplicate the code here to avoid exception handler
# which tends to screw up stack or leak
if
hasattr
(
val
,
fmt
):
val
=
_get
(
val
,
fmt
)()
elif
special_formats
.
has_key
(
fmt
):
if
fmt
==
'html-quote'
and
\
isinstance
(
val
,
TaintedString
):
# TaintedStrings will be quoted by default, don't
# double quote.
pass
else
:
val
=
special_formats
[
fmt
](
val
,
name
,
md
)
elif
fmt
==
''
:
val
=
''
else
:
if
isinstance
(
val
,
TaintedString
):
val
=
TaintedString
(
fmt
%
val
)
else
:
val
=
fmt
%
val
# finally, pump it through the actual string format...
fmt
=
self
.
fmt
if
fmt
==
's'
:
# Keep tainted strings as tainted strings here.
if
not
isinstance
(
val
,
TaintedString
):
val
=
ustr
(
val
)
else
:
# Keep tainted strings as tainted strings here.
wastainted
=
0
if
isinstance
(
val
,
TaintedString
):
wastainted
=
1
val
=
(
'%'
+
self
.
fmt
)
%
(
val
,)
if
wastainted
and
'<'
in
val
:
val
=
TaintedString
(
val
)
# next, look for upper, lower, etc
for
f
in
self
.
modifiers
:
if
f
.
__name__
==
'html_quote'
and
isinstance
(
val
,
TaintedString
):
# TaintedStrings will be quoted by default, don't double quote.
continue
val
=
f
(
val
)
if
have_arg
(
'size'
):
size
=
args
[
'size'
]
try
:
size
=
int
(
size
)
except
:
raise
ValueError
,(
'''a <code>size</code> attribute was used in a <code>var</code>
tag with a non-integer value.'''
)
if
len
(
val
)
>
size
:
val
=
val
[:
size
]
l
=
val
.
rfind
(
' '
)
if
l
>
size
/
2
:
val
=
val
[:
l
+
1
]
if
have_arg
(
'etc'
):
l
=
args
[
'etc'
]
else
:
l
=
'...'
val
=
val
+
l
if
isinstance
(
val
,
TaintedString
):
val
=
val
.
quoted
()
return
val
__call__
=
render
class
Call
:
name
=
'call'
expr
=
None
def
__init__
(
self
,
args
):
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
)
name
,
expr
=
name_param
(
args
,
'call'
,
1
)
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
simple_form
=
(
'i'
,
expr
,
None
)
def
url_quote
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
quote
(
str
(
v
))
def
url_quote_plus
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
quote_plus
(
str
(
v
))
def
url_unquote
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
unquote
(
str
(
v
))
def
url_unquote_plus
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
unquote_plus
(
str
(
v
))
def
newline_to_br
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
# Unsafe data is explicitly quoted here; we don't expect this to be HTML
# quoted later on anyway.
if
isinstance
(
v
,
TaintedString
):
v
=
v
.
quoted
()
v
=
ustr
(
v
)
v
=
v
.
replace
(
'
\
r
'
,
''
)
v
=
v
.
replace
(
'
\
n
'
,
'<br />
\
n
'
)
return
v
def
whole_dollars
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
try
:
return
"$%d"
%
v
except
:
return
''
def
dollars_and_cents
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
try
:
return
"$%.2f"
%
v
except
:
return
''
def
thousands_commas
(
v
,
name
=
'(Unknown name)'
,
md
=
{},
thou
=
re
.
compile
(
r"([0-9])([0-9][0-9][0-9]([,.]|$))"
).
search
):
v
=
str
(
v
)
vl
=
v
.
split
(
'.'
)
if
not
vl
:
return
v
v
=
vl
[
0
]
del
vl
[
0
]
if
vl
:
s
=
'.'
+
'.'
.
join
(
vl
)
else
:
s
=
''
mo
=
thou
(
v
)
while
mo
is
not
None
:
l
=
mo
.
start
(
0
)
v
=
v
[:
l
+
1
]
+
','
+
v
[
l
+
1
:]
mo
=
thou
(
v
)
return
v
+
s
def
whole_dollars_with_commas
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
try
:
v
=
"$%d"
%
v
except
:
v
=
''
return
thousands_commas
(
v
)
def
dollars_and_cents_with_commas
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
try
:
v
=
"$%.2f"
%
v
except
:
v
=
''
return
thousands_commas
(
v
)
def
len_format
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
str
(
len
(
v
))
def
len_comma
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
thousands_commas
(
str
(
len
(
v
)))
def
restructured_text
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
try
:
from
reStructuredText
import
HTML
except
ImportError
:
logger
.
info
(
'The reStructuredText package is not available, therefor '
'the DT_Var.restructured_text function returns None.'
)
return
None
if
isinstance
(
v
,
str
):
txt
=
v
elif
aq_base
(
v
).
meta_type
in
[
'DTML Document'
,
'DTML Method'
]:
txt
=
aq_base
(
v
).
read_raw
()
else
:
txt
=
str
(
v
)
return
HTML
(
txt
)
def
structured_text
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
from
zope.structuredtext.html
import
HTML
if
isinstance
(
v
,
str
):
txt
=
v
elif
aq_base
(
v
).
meta_type
in
[
'DTML Document'
,
'DTML Method'
]:
txt
=
aq_base
(
v
).
read_raw
()
else
:
txt
=
str
(
v
)
level
=
3
try
:
from
App.config
import
getConfiguration
except
ImportError
:
pass
else
:
level
=
getConfiguration
().
structured_text_header_level
doc
=
DocumentWithImages
()(
txt
)
return
HTML
()(
doc
,
level
,
header
=
False
)
def
sql_quote
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
"""Quote single quotes in a string by doubling them.
This is needed to securely insert values into sql
string literals in templates that generate sql.
"""
if
v
.
find
(
"'"
)
>=
0
:
return
v
.
replace
(
"'"
,
"''"
)
return
v
special_formats
=
{
'whole-dollars'
:
whole_dollars
,
'dollars-and-cents'
:
dollars_and_cents
,
'collection-length'
:
len_format
,
'structured-text'
:
structured_text
,
'restructured-text'
:
restructured_text
,
# The rest are deprecated:
'sql-quote'
:
sql_quote
,
'html-quote'
:
html_quote
,
'url-quote'
:
url_quote
,
'url-quote-plus'
:
url_quote_plus
,
'url-unquote'
:
url_unquote
,
'url-unquote-plus'
:
url_unquote_plus
,
'multi-line'
:
newline_to_br
,
'comma-numeric'
:
thousands_commas
,
'dollars-with-commas'
:
whole_dollars_with_commas
,
'dollars-and-cents-with-commas'
:
dollars_and_cents_with_commas
,
}
def
spacify
(
val
):
if
val
.
find
(
'_'
)
>=
0
:
val
=
val
.
replace
(
'_'
,
' '
)
return
val
modifiers
=
(
html_quote
,
url_quote
,
url_quote_plus
,
url_unquote
,
url_unquote_plus
,
newline_to_br
,
string
.
lower
,
string
.
upper
,
string
.
capitalize
,
spacify
,
thousands_commas
,
sql_quote
,
url_unquote
,
url_unquote_plus
)
modifiers
=
map
(
lambda
f
:
(
f
.
__name__
,
f
),
modifiers
)
class
Comment
:
'''Comments
The 'comment' tag can be used to simply include comments
in DTML source.
For example::
<!--#comment-->
This text is not rendered.
<!--#/comment-->
'''
name
=
'comment'
blockContinuations
=
()
def
__init__
(
self
,
args
,
fmt
=
''
):
pass
def
render
(
self
,
md
):
return
''
__call__
=
render
src/DocumentTemplate/DT_With.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
'''Nested namespace access
The 'with' tag is used to introduce nested namespaces.
The text enclosed in the with tag is rendered using information
from the given variable or expression.
For example, if the variable 'person' is bound to an object that
has attributes 'name' and 'age', then a 'with' tag like the
following can be used to access these attributes::
<!--#with person-->
<!--#var name-->,
<!--#var age-->
<!--#/with-->
Eather a 'name' or an 'expr' attribute may be used to specify data.
A 'mapping' attribute may be used to indicate that the given data
should be treated as mapping object, rather than as an object with
named attributes.
'''
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.15 $'
[
11
:
-
2
]
from
DocumentTemplate.DT_Util
import
parse_params
,
name_param
from
DocumentTemplate.DT_Util
import
InstanceDict
,
render_blocks
,
str
from
DocumentTemplate.DT_Util
import
TemplateDict
class
With
:
blockContinuations
=
()
name
=
'with'
mapping
=
None
only
=
0
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
args
=
parse_params
(
args
,
name
=
''
,
expr
=
''
,
mapping
=
1
,
only
=
1
)
name
,
expr
=
name_param
(
args
,
'with'
,
1
)
if
expr
is
None
:
expr
=
name
else
:
expr
=
expr
.
eval
self
.
__name__
,
self
.
expr
=
name
,
expr
self
.
section
=
section
.
blocks
if
args
.
has_key
(
'mapping'
)
and
args
[
'mapping'
]:
self
.
mapping
=
1
if
args
.
has_key
(
'only'
)
and
args
[
'only'
]:
self
.
only
=
1
def
render
(
self
,
md
):
expr
=
self
.
expr
if
type
(
expr
)
is
type
(
''
):
v
=
md
[
expr
]
else
:
v
=
expr
(
md
)
if
not
self
.
mapping
:
if
type
(
v
)
is
type
(())
and
len
(
v
)
==
1
:
v
=
v
[
0
]
v
=
InstanceDict
(
v
,
md
)
if
self
.
only
:
_md
=
md
md
=
TemplateDict
()
if
hasattr
(
_md
,
'guarded_getattr'
):
md
.
guarded_getattr
=
_md
.
guarded_getattr
if
hasattr
(
_md
,
'guarded_getitem'
):
md
.
guarded_getitem
=
_md
.
guarded_getitem
md
.
_push
(
v
)
try
:
return
render_blocks
(
self
.
section
,
md
)
finally
:
md
.
_pop
(
1
)
__call__
=
render
src/DocumentTemplate/DTtestExpr.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__doc__
=
'''short description
$Id$'''
__version__
=
'$Revision: 1.8 $'
[
11
:
-
2
]
from
DocumentTemplate
import
*
import
sys
def
test1
():
print
HTML
(
'area code=<!--#var expr="phone[:3]"-->'
)(
phone
=
'7035551212'
)
def
test2
():
print
HTML
(
'area code=<!--#var expr="phone.number"-->'
)(
phone
=
'7035551212'
)
def
test3
():
print
HTML
(
'area code=<!--#var expr="phone*1000"-->'
)(
phone
=
'7035551212'
)
def
test4
():
h
=
HTML
(
"""
<!--#if expr="level==1"-->
level was 1
<!--#elif expr="level==2"-->
level was 2
<!--#elif expr="level==3"-->
level was 3
<!--#else-->
level was something else
<!--#endif-->
"""
)
for
i
in
range
(
4
):
print
'-'
*
77
print
i
,
h
(
level
=
i
)
print
'-'
*
77
if
__name__
==
"__main__"
:
try
:
command
=
sys
.
argv
[
1
]
except
:
command
=
'main'
globals
()[
command
]()
src/DocumentTemplate/Let.stx
deleted
100644 → 0
View file @
13bc9b23
The let tag:
is a new tag that lets you create blocks like:
<!--#in "1,2,3,4"-->
<!--#let num=sequence-item
index=sequence-index
result="num*index"-->
<!--#var num--> * <!--#var index--> = <!--#var result-->
<!--#/let-->
<!--#/in-->
Which yields:
1 * 0 = 0
2 * 1 = 2
3 * 2 = 6
4 * 3 = 12
The #let tag works like the #with tag, but is more flexible in that
it allows you to make multiple assignments, and allows you to chain
assignments, using earlier declarations in later assignments. Notice
inthe ablove example, the 'result' variable is based on 'num' and
'index', both of which are assigned in the same #let expression.
Syntacticly, each argument to be evalulated in the head of the let
tag must be seperated by a newline. Enclosing an argument in double
quotes causes it to be evaluated by the DTML expression machinery.
Un-quoted arguments are referenced by name.
Evaluation is in sequence with the result of earlier assignments
available to later ones. Later assignments can also override earlier
ones, which can be helpful for longer step-by-step calculations. The
variables thus set are in effect for the life of the <!--#let-->
block.
src/DocumentTemplate/VSEval.py
deleted
100644 → 0
View file @
13bc9b23
# alias module for backwards compatibility
from
DocumentTemplate.DT_Util
import
Eval
def
careful_mul
(
env
,
*
factors
):
r
=
1
for
factor
in
factors
:
r
=
r
*
factor
return
r
src/DocumentTemplate/_DocumentTemplate.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
'''Document templates with fill-in fields
Document templates provide for creation of textual documents, such as
HTML pages, from template source by inserting data from python objects
and name-spaces.
When a document template is created, a collection of default values to
be inserted may be specified with a mapping object and with keyword
arguments.
A document templated may be called to create a document with values
inserted. When called, an instance, a mapping object, and keyword
arguments may be specified to provide values to be inserted. If an
instance is provided, the document template will try to look up values
in the instance using getattr, so inheritence of values is supported.
If an inserted value is a function, method, or class, then an attempt
will be made to call the object to obtain values. This allows
instance methods to be included in documents.
Document templates masquerade as functions, so the python object
publisher (Bobo) will call templates that are stored as instances of
published objects. Bobo will pass the object the template was found in
and the HTTP request object.
Two source formats are supported:
Extended Python format strings (EPFS) --
This format is based on the insertion by name format strings
of python with additional format characters, '[' and ']' to
indicate block boundaries. In addition, parameters may be
used within formats to control how insertion is done.
For example:
%%(date fmt=DayOfWeek upper)s
causes the contents of variable 'date' to be inserted using
custom format 'DayOfWeek' and with all lower case letters
converted to upper case.
HTML --
This format uses HTML server-side-include syntax with
commands for inserting text. Parameters may be included to
customize the operation of a command.
For example:
<!--#var total fmt=12.2f-->
is used to insert the variable 'total' with the C format
'12.2f'.
Document templates support conditional and sequence insertion
Document templates extend python string substitition rules with a
mechanism that allows conditional insertion of template text and that
allows sequences to be inserted with element-wise insertion of
template text.
Access Control
Document templates provide a basic level of access control by
preventing access to names beginning with an underscore.
Additional control may be provided by providing document templates
with a 'guarded_getattr' and 'guarded_getitem' method. This would
typically be done by subclassing one or more of the DocumentTemplate
classes.
If provided, the the 'guarded_getattr' method will be called when
objects are accessed as instance attributes or when they are
accessed through keyed access in an expression.
Document Templates may be created 4 ways:
DocumentTemplate.String -- Creates a document templated from a
string using an extended form of python string formatting.
DocumentTemplate.File -- Creates a document templated bound to a
named file using an extended form of python string formatting.
If the object is pickled, the file name, rather than the file
contents is pickled. When the object is unpickled, then the
file will be re-read to obtain the string. Note that the file
will not be read until the document template is used the first
time.
DocumentTemplate.HTML -- Creates a document templated from a
string using HTML server-side-include rather than
python-format-string syntax.
DocumentTemplate.HTMLFile -- Creates an HTML document template
from a named file.
'''
__version__
=
'$Revision: 1.14 $'
[
11
:
-
2
]
from
DocumentTemplate.DT_Raise
import
ParseError
from
DocumentTemplate.DT_String
import
String
,
File
from
DocumentTemplate.DT_HTML
import
HTML
,
HTMLFile
,
HTMLDefault
# import DT_UI # Install HTML editing
src/DocumentTemplate/__init__.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Package wrapper for Document Template
This wrapper allows the (now many) document template modules to be
segregated in a separate package."""
from
DocumentTemplate.DT_String
import
String
,
File
from
DocumentTemplate.DT_HTML
import
HTML
,
HTMLDefault
,
HTMLFile
# Register the dtml-tree tag
import
TreeDisplay
from
DocumentTemplate
import
security
# Side effects!
del
security
src/DocumentTemplate/cDocumentTemplate.c
deleted
100644 → 0
View file @
13bc9b23
/*****************************************************************************
Copyright (c) 2002 Zope Foundation and Contributors.
This software is subject to the provisions of the Zope Public License,
Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
FOR A PARTICULAR PURPOSE
****************************************************************************/
static
char
cDocumentTemplate_module_documentation
[]
=
""
"
\n
$Id$"
;
#include "ExtensionClass/ExtensionClass.h"
static
PyObject
*
py_isDocTemp
=
0
,
*
py_blocks
=
0
,
*
py_
=
0
,
*
join
=
0
,
*
py_acquire
;
static
PyObject
*
py___call__
,
*
py___roles__
,
*
py_AUTHENTICATED_USER
;
static
PyObject
*
py__proxy_roles
,
*
py_Unauthorized
;
static
PyObject
*
py_Unauthorized_fmt
,
*
py_guarded_getattr
;
static
PyObject
*
py__push
,
*
py__pop
,
*
py_aq_base
,
*
py_renderNS
;
static
PyObject
*
py___class__
,
*
html_quote
,
*
ustr
,
*
untaint_name
;
/* ----------------------------------------------------- */
static
void
PyVar_Assign
(
PyObject
**
v
,
PyObject
*
e
)
{
Py_XDECREF
(
*
v
);
*
v
=
e
;}
#define ASSIGN(V,E) PyVar_Assign(&(V),(E))
#define UNLESS(E) if (!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E); UNLESS(V)
#define OBJECT(O)(((PyObject*)O))
typedef
struct
{
PyObject_HEAD
PyObject
*
inst
;
PyObject
*
cache
;
PyObject
*
namespace
;
PyObject
*
guarded_getattr
;
}
InstanceDictobject
;
staticforward
PyExtensionClass
InstanceDictType
;
staticforward
PyObject
*
_join_unicode
(
PyObject
*
prejoin
);
static
PyObject
*
InstanceDict___init__
(
InstanceDictobject
*
self
,
PyObject
*
args
)
{
self
->
guarded_getattr
=
NULL
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO|O"
,
&
(
self
->
inst
),
&
(
self
->
namespace
),
&
(
self
->
guarded_getattr
)))
return
NULL
;
Py_INCREF
(
self
->
inst
);
Py_INCREF
(
self
->
namespace
);
if
(
self
->
guarded_getattr
)
Py_INCREF
(
self
->
guarded_getattr
);
else
UNLESS
(
self
->
guarded_getattr
=
PyObject_GetAttr
(
self
->
namespace
,
py_guarded_getattr
))
return
NULL
;
UNLESS
(
self
->
cache
=
PyDict_New
())
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
struct
PyMethodDef
InstanceDict_methods
[]
=
{
{
"__init__"
,
(
PyCFunction
)
InstanceDict___init__
,
1
,
""
},
{
NULL
,
NULL
}
/* sentinel */
};
/* ---------- */
static
void
InstanceDict_dealloc
(
InstanceDictobject
*
self
)
{
Py_XDECREF
(
self
->
inst
);
Py_XDECREF
(
self
->
cache
);
Py_XDECREF
(
self
->
namespace
);
Py_XDECREF
(
self
->
guarded_getattr
);
Py_DECREF
(
self
->
ob_type
);
PyObject_DEL
(
self
);
}
static
PyObject
*
InstanceDict_getattr
(
InstanceDictobject
*
self
,
PyObject
*
name
)
{
return
Py_FindAttr
((
PyObject
*
)
self
,
name
);
}
static
PyObject
*
InstanceDict_repr
(
InstanceDictobject
*
self
)
{
return
PyObject_Repr
(
self
->
inst
);
}
/* Code to access InstanceDict objects as mappings */
static
int
InstanceDict_length
(
InstanceDictobject
*
self
)
{
return
1
;
}
static
PyObject
*
InstanceDict_subscript
(
InstanceDictobject
*
self
,
PyObject
*
key
)
{
PyObject
*
r
,
*
v
;
char
*
name
;
/* Try to get value from the cache */
if
((
r
=
PyObject_GetItem
(
self
->
cache
,
key
)))
return
r
;
PyErr_Clear
();
/* Check for __str__ */
UNLESS
(
name
=
PyString_AsString
(
key
))
return
NULL
;
if
(
*
name
==
'_'
)
{
UNLESS
(
strcmp
(
name
,
"__str__"
)
==
0
)
goto
KeyError
;
return
PyObject_Str
(
self
->
inst
);
}
if
(
self
->
guarded_getattr
!=
Py_None
)
{
r
=
PyObject_CallFunction
(
self
->
guarded_getattr
,
"OO"
,
self
->
inst
,
key
);
}
else
{
r
=
PyObject_GetAttr
(
self
->
inst
,
key
);
}
if
(
!
r
)
{
PyObject
*
tb
;
PyErr_Fetch
(
&
r
,
&
v
,
&
tb
);
if
(
r
!=
PyExc_AttributeError
)
/* || PyObject_Compare(v,key)) */
{
PyErr_Restore
(
r
,
v
,
tb
);
return
NULL
;
}
Py_XDECREF
(
r
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
goto
KeyError
;
}
if
(
r
&&
PyObject_SetItem
(
self
->
cache
,
key
,
r
)
<
0
)
PyErr_Clear
();
return
r
;
KeyError:
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
int
InstanceDict_ass_sub
(
InstanceDictobject
*
self
,
PyObject
*
v
,
PyObject
*
w
)
{
PyErr_SetString
(
PyExc_TypeError
,
"InstanceDict objects do not support item assignment"
);
return
-
1
;
}
static
PyMappingMethods
InstanceDict_as_mapping
=
{
(
inquiry
)
InstanceDict_length
,
/*mp_length*/
(
binaryfunc
)
InstanceDict_subscript
,
/*mp_subscript*/
(
objobjargproc
)
InstanceDict_ass_sub
,
/*mp_ass_subscript*/
};
/* -------------------------------------------------------- */
static
char
InstanceDicttype__doc__
[]
=
""
;
static
PyExtensionClass
InstanceDictType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"InstanceDict"
,
/*tp_name*/
sizeof
(
InstanceDictobject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
InstanceDict_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*obsolete tp_getattr*/
(
setattrfunc
)
0
,
/*obsolete tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
InstanceDict_repr
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
InstanceDict_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
InstanceDict_getattr
,
/*tp_getattro*/
0
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
InstanceDicttype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
InstanceDict_methods
)
};
typedef
struct
{
PyObject_HEAD
int
level
;
PyObject
*
dict
;
PyObject
*
data
;
}
MM
;
staticforward
PyExtensionClass
MMtype
;
static
PyObject
*
MM_push
(
MM
*
self
,
PyObject
*
args
)
{
PyObject
*
src
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
src
))
return
NULL
;
UNLESS
(
-
1
!=
PyList_Append
(
self
->
data
,
src
))
return
NULL
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
MM_pop
(
MM
*
self
,
PyObject
*
args
)
{
int
i
=
1
,
l
;
PyObject
*
r
;
if
(
args
)
UNLESS
(
PyArg_Parse
(
args
,
"i"
,
&
i
))
return
NULL
;
if
((
l
=
PyList_Size
(
self
->
data
))
<
0
)
return
NULL
;
i
=
l
-
i
;
UNLESS
(
r
=
PySequence_GetItem
(
self
->
data
,
l
-
1
))
return
NULL
;
if
(
PyList_SetSlice
(
self
->
data
,
i
,
l
,
NULL
)
<
0
)
goto
err
;
return
r
;
err:
Py_DECREF
(
r
);
return
NULL
;
}
static
PyObject
*
MM__init__
(
MM
*
self
,
PyObject
*
args
)
{
UNLESS
(
PyArg_Parse
(
args
,
""
))
return
NULL
;
UNLESS
(
self
->
data
=
PyList_New
(
0
))
return
NULL
;
self
->
dict
=
NULL
;
self
->
level
=
0
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
int
safe_PyCallable_Check
(
PyObject
*
x
)
{
PyObject
*
klass
;
if
(
x
==
NULL
)
return
0
;
klass
=
PyObject_GetAttr
(
x
,
py___class__
);
if
(
klass
)
{
PyObject
*
call
=
PyObject_GetAttr
(
x
,
py___call__
);
if
(
call
)
{
Py_DECREF
(
klass
);
Py_DECREF
(
call
);
return
1
;
}
else
{
PyErr_Clear
();
Py_DECREF
(
klass
);
if
(
PyClass_Check
(
x
)
||
PyExtensionClass_Check
(
x
))
return
1
;
else
return
0
;
}
}
else
{
PyErr_Clear
();
return
PyCallable_Check
(
x
);
}
}
static
int
dtObjectIsCallable
(
PyObject
*
ob
)
{
PyObject
*
base
=
0
;
int
result
=
0
;
/* Ensure that an object is really callable by unwrapping it */
UNLESS
(
base
=
PyObject_GetAttr
(
ob
,
py_aq_base
))
{
PyErr_Clear
();
return
safe_PyCallable_Check
(
ob
);
}
result
=
safe_PyCallable_Check
(
base
);
Py_DECREF
(
base
);
return
result
;
}
static
int
dtObjectIsDocTemp
(
PyObject
*
ob
)
{
PyObject
*
base
=
0
;
PyObject
*
value
=
0
;
int
result
=
0
;
/* Ensure that 'isDocTemp' is not acquired */
UNLESS
(
base
=
PyObject_GetAttr
(
ob
,
py_aq_base
))
{
PyErr_Clear
();
base
=
ob
;
Py_INCREF
(
base
);
}
if
(
(
value
=
PyObject_GetAttr
(
base
,
py_isDocTemp
))
)
{
if
(
PyObject_IsTrue
(
value
))
{
result
=
1
;
}
Py_DECREF
(
value
);
}
else
PyErr_Clear
();
Py_DECREF
(
base
);
return
result
;
}
static
PyObject
*
MM_cget
(
MM
*
self
,
PyObject
*
key
,
int
call
)
{
long
i
;
PyObject
*
e
,
*
rr
;
UNLESS
(
-
1
!=
(
i
=
PyList_Size
(
self
->
data
)))
return
NULL
;
while
(
--
i
>=
0
)
{
e
=
PyList_GET_ITEM
(
self
->
data
,
i
);
if
(
PyDict_Check
(
e
))
{
e
=
PyDict_GetItem
(
e
,
key
);
Py_XINCREF
(
e
);
}
else
{
UNLESS
(
e
=
PyObject_GetItem
(
e
,
key
))
{
if
(
PyErr_Occurred
()
==
PyExc_KeyError
)
PyErr_Clear
();
else
return
NULL
;
}
}
if
(
e
)
{
if
(
!
call
)
return
e
;
/* Try calling __render_with_namespace__ */
if
((
rr
=
PyObject_GetAttr
(
e
,
py_renderNS
)))
{
Py_DECREF
(
e
);
UNLESS_ASSIGN
(
rr
,
PyObject_CallFunction
(
rr
,
"O"
,
self
))
return
NULL
;
return
rr
;
}
else
PyErr_Clear
();
if
(
dtObjectIsCallable
(
e
))
{
/* Try calling the object */
if
(
dtObjectIsDocTemp
(
e
))
{
ASSIGN
(
e
,
PyObject_CallFunction
(
e
,
"OO"
,
Py_None
,
self
));
UNLESS
(
e
)
return
NULL
;
return
e
;
}
rr
=
PyObject_CallObject
(
e
,
NULL
);
if
(
rr
)
ASSIGN
(
e
,
rr
);
else
{
Py_DECREF
(
e
);
return
NULL
;
}
}
return
e
;
}
}
PyErr_SetObject
(
PyExc_KeyError
,
key
);
return
NULL
;
}
static
PyObject
*
MM_get
(
MM
*
self
,
PyObject
*
args
)
{
PyObject
*
key
,
*
call
=
Py_None
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O|O"
,
&
key
,
&
call
))
return
NULL
;
return
MM_cget
(
self
,
key
,
PyObject_IsTrue
(
call
));
}
static
PyObject
*
MM_has_key
(
MM
*
self
,
PyObject
*
args
)
{
PyObject
*
key
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
key
))
return
NULL
;
if
((
key
=
MM_cget
(
self
,
key
,
0
)))
{
Py_DECREF
(
key
);
return
PyInt_FromLong
(
1
);
}
PyErr_Clear
();
return
PyInt_FromLong
(
0
);
}
static
struct
PyMethodDef
MM_methods
[]
=
{
{
"__init__"
,
(
PyCFunction
)
MM__init__
,
0
,
"__init__() -- Create a new empty multi-mapping"
},
{
"_push"
,
(
PyCFunction
)
MM_push
,
0
,
"_push(mapping_object) -- Add a data source"
},
{
"_pop"
,
(
PyCFunction
)
MM_pop
,
0
,
"_pop() -- Remove and return the last data source added"
},
{
"getitem"
,
(
PyCFunction
)
MM_get
,
METH_VARARGS
,
"getitem(key[,call]) -- Get a value from the MultiDict
\n\n
"
"If call is true, callable objects that can be called without arguments are
\n
"
"called during retrieval.
\n
"
"If call is false, the object will be returns without any attempt to call it.
\n
"
"If not specified, call is false by default.
\n
"
},
{
"has_key"
,
(
PyCFunction
)
MM_has_key
,
METH_VARARGS
,
"has_key(key) -- Test whether the mapping has the given key"
},
{
NULL
,
NULL
}
/* sentinel */
};
static
void
MM_dealloc
(
MM
*
self
)
{
Py_XDECREF
(
self
->
data
);
Py_XDECREF
(
self
->
dict
);
Py_DECREF
(
self
->
ob_type
);
PyObject_DEL
(
self
);
}
static
PyObject
*
MM_getattro
(
MM
*
self
,
PyObject
*
name
)
{
if
(
PyString_Check
(
name
))
{
if
(
strcmp
(
PyString_AsString
(
name
),
"level"
)
==
0
)
return
PyInt_FromLong
(
self
->
level
);
}
if
(
self
->
dict
)
{
PyObject
*
v
;
if
((
v
=
PyDict_GetItem
(
self
->
dict
,
name
)))
{
Py_INCREF
(
v
);
return
v
;
}
}
return
Py_FindAttr
((
PyObject
*
)
self
,
name
);
}
static
int
MM_setattro
(
MM
*
self
,
PyObject
*
name
,
PyObject
*
v
)
{
if
(
v
&&
PyString_Check
(
name
))
{
if
(
strcmp
(
PyString_AsString
(
name
),
"level"
)
==
0
)
{
self
->
level
=
PyInt_AsLong
(
v
);
if
(
PyErr_Occurred
())
return
-
1
;
return
0
;
}
}
if
(
!
self
->
dict
&&
!
(
self
->
dict
=
PyDict_New
()))
return
-
1
;
if
(
v
)
return
PyDict_SetItem
(
self
->
dict
,
name
,
v
);
else
return
PyDict_DelItem
(
self
->
dict
,
name
);
}
static
int
MM_length
(
MM
*
self
)
{
long
l
=
0
,
el
,
i
;
PyObject
*
e
=
0
;
UNLESS
(
-
1
!=
(
i
=
PyList_Size
(
self
->
data
)))
return
-
1
;
while
(
--
i
>=
0
)
{
e
=
PyList_GetItem
(
self
->
data
,
i
);
UNLESS
(
-
1
!=
(
el
=
PyObject_Length
(
e
)))
return
-
1
;
l
+=
el
;
}
return
l
;
}
static
PyObject
*
MM_subscript
(
MM
*
self
,
PyObject
*
key
)
{
return
MM_cget
(
self
,
key
,
1
);
}
typedef
struct
{
PyObject_HEAD
PyObject
*
data
;
}
DictInstance
;
static
void
DictInstance_dealloc
(
DictInstance
*
self
)
{
Py_DECREF
(
self
->
data
);
PyObject_DEL
(
self
);
}
static
PyObject
*
DictInstance_getattr
(
DictInstance
*
self
,
PyObject
*
name
)
{
PyObject
*
r
;
if
((
r
=
PyObject_GetItem
(
self
->
data
,
name
)))
return
r
;
PyErr_SetObject
(
PyExc_AttributeError
,
name
);
return
NULL
;
}
static
PyTypeObject
DictInstanceType
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"DictInstance"
,
/*tp_name*/
sizeof
(
DictInstance
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
(
destructor
)
DictInstance_dealloc
,
(
printfunc
)
0
,
(
getattrfunc
)
0
,
(
setattrfunc
)
0
,
(
cmpfunc
)
0
,
(
reprfunc
)
0
,
0
,
0
,
0
,
(
hashfunc
)
0
,
(
ternaryfunc
)
0
,
(
reprfunc
)
0
,
(
getattrofunc
)
DictInstance_getattr
,
(
setattrofunc
)
0
,
0L
,
0L
,
"Wrap a mapping object to look like an instance"
};
static
DictInstance
*
newDictInstance
(
PyObject
*
data
)
{
DictInstance
*
self
;
UNLESS
(
self
=
PyObject_NEW
(
DictInstance
,
&
DictInstanceType
))
return
NULL
;
self
->
data
=
data
;
Py_INCREF
(
data
);
return
self
;
}
static
PyObject
*
MM_call
(
MM
*
self
,
PyObject
*
args
,
PyObject
*
kw
)
{
PyObject
*
r
,
*
t
;
int
i
,
l
=
0
;
if
(
args
&&
(
l
=
PyTuple_Size
(
args
))
<
0
)
return
NULL
;
if
(
l
)
{
UNLESS
(
r
=
PyObject_CallObject
(
OBJECT
(
self
->
ob_type
),
NULL
))
return
NULL
;
for
(
i
=
0
;
i
<
l
;
i
++
)
if
(
PyList_Append
(((
MM
*
)
r
)
->
data
,
PyTuple_GET_ITEM
(
args
,
i
))
<
0
)
goto
err
;
if
(
kw
&&
PyList_Append
(((
MM
*
)
r
)
->
data
,
kw
)
<
0
)
goto
err
;
}
else
{
if
(
!
kw
)
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
r
=
kw
;
Py_INCREF
(
r
);
}
ASSIGN
(
r
,
OBJECT
(
newDictInstance
(
r
)));
UNLESS
(
t
=
PyTuple_New
(
1
))
goto
err
;
PyTuple_SET_ITEM
(
t
,
0
,
r
);
return
t
;
err:
Py_XDECREF
(
r
);
return
NULL
;
}
static
PyMappingMethods
MM_as_mapping
=
{
(
inquiry
)
MM_length
,
/*mp_length*/
(
binaryfunc
)
MM_subscript
,
/*mp_subscript*/
(
objobjargproc
)
NULL
,
/*mp_ass_subscript*/
};
/* -------------------------------------------------------- */
static
char
MMtype__doc__
[]
=
"TemplateDict -- Combine multiple mapping objects for lookup"
;
static
PyExtensionClass
MMtype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"TemplateDict"
,
/*tp_name*/
sizeof
(
MM
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
MM_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
&
MM_as_mapping
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
MM_call
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
MM_getattro
,
/*tp_getattro*/
(
setattrofunc
)
MM_setattro
,
/*tp_setattro*/
/* Space for future expansion */
0L
,
0L
,
MMtype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
MM_methods
)
};
/* List of methods defined in the module */
static
int
if_finally
(
PyObject
*
md
,
int
err
)
{
PyObject
*
t
,
*
v
,
*
tb
;
if
(
err
)
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
md
=
PyObject_GetAttr
(
md
,
py__pop
);
if
(
md
)
ASSIGN
(
md
,
PyObject_CallObject
(
md
,
NULL
));
if
(
err
)
PyErr_Restore
(
t
,
v
,
tb
);
if
(
md
)
{
Py_DECREF
(
md
);
return
-
1
;
}
else
return
-
2
;
}
static
int
render_blocks_
(
PyObject
*
blocks
,
PyObject
*
rendered
,
PyObject
*
md
,
PyObject
*
mda
)
{
PyObject
*
block
,
*
t
,
*
args
;
int
l
,
i
,
k
=
0
,
append
;
int
skip_html_quote
;
if
((
l
=
PyList_Size
(
blocks
))
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
block
=
PyList_GET_ITEM
(((
PyListObject
*
)
blocks
),
i
);
append
=
1
;
if
(
PyTuple_Check
(
block
)
&&
PyTuple_GET_SIZE
(
block
)
>
1
&&
PyTuple_GET_ITEM
(
block
,
0
)
&&
PyString_Check
(
PyTuple_GET_ITEM
(
block
,
0
)))
{
switch
(
PyString_AS_STRING
(
PyTuple_GET_ITEM
(
block
,
0
))[
0
])
{
case
'v'
:
/* var */
t
=
PyTuple_GET_ITEM
(
block
,
1
);
if
(
t
==
NULL
)
return
-
1
;
if
(
PyString_Check
(
t
))
t
=
PyObject_GetItem
(
md
,
t
);
else
t
=
PyObject_CallObject
(
t
,
mda
);
if
(
t
==
NULL
)
return
-
1
;
skip_html_quote
=
0
;
if
(
!
(
PyString_Check
(
t
)
||
PyUnicode_Check
(
t
)
)
)
{
/* This might be a TaintedString object */
PyObject
*
untaintmethod
=
NULL
;
untaintmethod
=
PyObject_GetAttr
(
t
,
untaint_name
);
if
(
untaintmethod
)
{
/* Quote it */
UNLESS_ASSIGN
(
t
,
PyObject_CallObject
(
untaintmethod
,
NULL
))
return
-
1
;
skip_html_quote
=
1
;
}
else
PyErr_Clear
();
Py_XDECREF
(
untaintmethod
);
}
if
(
!
(
PyString_Check
(
t
)
||
PyUnicode_Check
(
t
)
)
)
{
args
=
PyTuple_New
(
1
);
if
(
!
args
)
return
-
1
;
PyTuple_SET_ITEM
(
args
,
0
,
t
);
t
=
PyObject_CallObject
(
ustr
,
args
);
Py_DECREF
(
args
);
args
=
NULL
;
UNLESS
(
t
)
return
-
1
;
}
if
(
skip_html_quote
==
0
&&
PyTuple_GET_SIZE
(
block
)
==
3
)
/* html_quote */
{
if
(
PyString_Check
(
t
))
{
if
(
strchr
(
PyString_AS_STRING
(
t
),
'&'
)
||
strchr
(
PyString_AS_STRING
(
t
),
'<'
)
||
strchr
(
PyString_AS_STRING
(
t
),
'>'
)
||
strchr
(
PyString_AS_STRING
(
t
),
'"'
)
)
{
/* string includes html problem characters, so
we cant skip the quoting process */
skip_html_quote
=
0
;
}
else
{
skip_html_quote
=
1
;
}
}
else
{
/* never skip the quoting for unicode strings */
skip_html_quote
=
0
;
}
if
(
!
skip_html_quote
)
{
ASSIGN
(
t
,
PyObject_CallFunction
(
html_quote
,
"O"
,
t
));
if
(
t
==
NULL
)
return
-
1
;
}
}
block
=
t
;
break
;
case
'i'
:
/* if */
{
int
icond
,
m
,
bs
;
PyObject
*
cond
,
*
n
,
*
cache
;
bs
=
PyTuple_GET_SIZE
(
block
)
-
1
;
/* subtract code */
UNLESS
(
cache
=
PyDict_New
())
return
-
1
;
cond
=
PyObject_GetAttr
(
md
,
py__push
);
if
(
cond
)
ASSIGN
(
cond
,
PyObject_CallFunction
(
cond
,
"O"
,
cache
));
Py_DECREF
(
cache
);
if
(
cond
)
Py_DECREF
(
cond
);
else
return
-
1
;
append
=
0
;
m
=
bs
-
1
;
for
(
icond
=
0
;
icond
<
m
;
icond
+=
2
)
{
cond
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
);
if
(
PyString_Check
(
cond
))
{
/* We have to be careful to handle key errors here */
n
=
cond
;
if
((
cond
=
PyObject_GetItem
(
md
,
cond
)))
{
if
(
PyDict_SetItem
(
cache
,
n
,
cond
)
<
0
)
{
Py_DECREF
(
cond
);
return
if_finally
(
md
,
1
);
}
}
else
{
PyObject
*
t
,
*
v
,
*
tb
;
PyErr_Fetch
(
&
t
,
&
v
,
&
tb
);
if
(
t
!=
PyExc_KeyError
||
PyObject_Compare
(
v
,
n
))
{
PyErr_Restore
(
t
,
v
,
tb
);
return
if_finally
(
md
,
1
);
}
Py_XDECREF
(
t
);
Py_XDECREF
(
v
);
Py_XDECREF
(
tb
);
cond
=
Py_None
;
Py_INCREF
(
cond
);
}
}
else
UNLESS
(
cond
=
PyObject_CallObject
(
cond
,
mda
))
return
if_finally
(
md
,
1
);
if
(
PyObject_IsTrue
(
cond
))
{
Py_DECREF
(
cond
);
block
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
+
1
);
if
(
block
!=
Py_None
&&
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
return
if_finally
(
md
,
1
);
m
=-
1
;
break
;
}
else
Py_DECREF
(
cond
);
}
if
(
icond
==
m
)
{
block
=
PyTuple_GET_ITEM
(
block
,
icond
+
1
);
if
(
block
!=
Py_None
&&
render_blocks_
(
block
,
rendered
,
md
,
mda
)
<
0
)
return
if_finally
(
md
,
1
);
}
if
(
if_finally
(
md
,
0
)
==
-
2
)
return
-
1
;
}
break
;
default:
PyErr_Format
(
PyExc_ValueError
,
"Invalid DTML command code, %s"
,
PyString_AS_STRING
(
PyTuple_GET_ITEM
(
block
,
0
)));
return
-
1
;
}
}
else
if
(
PyString_Check
(
block
)
||
PyUnicode_Check
(
block
))
{
Py_INCREF
(
block
);
}
else
{
UNLESS
(
block
=
PyObject_CallObject
(
block
,
mda
))
return
-
1
;
}
if
(
append
&&
PyObject_IsTrue
(
block
))
{
k
=
PyList_Append
(
rendered
,
block
);
Py_DECREF
(
block
);
if
(
k
<
0
)
return
-
1
;
}
}
return
0
;
}
static
PyObject
*
render_blocks
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
md
,
*
blocks
,
*
mda
=
0
,
*
rendered
=
0
;
int
l
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"OO"
,
&
blocks
,
&
md
))
return
NULL
;
UNLESS
(
rendered
=
PyList_New
(
0
))
goto
err
;
UNLESS
(
mda
=
Py_BuildValue
(
"(O)"
,
md
))
goto
err
;
if
(
render_blocks_
(
blocks
,
rendered
,
md
,
mda
)
<
0
)
goto
err
;
Py_DECREF
(
mda
);
l
=
PyList_Size
(
rendered
);
if
(
l
==
0
)
{
Py_INCREF
(
py_
);
ASSIGN
(
rendered
,
py_
);
}
else
if
(
l
==
1
)
ASSIGN
(
rendered
,
PySequence_GetItem
(
rendered
,
0
));
else
ASSIGN
(
rendered
,
_join_unicode
(
rendered
));
return
rendered
;
err:
Py_XDECREF
(
mda
);
Py_XDECREF
(
rendered
);
return
NULL
;
}
static
PyObject
*
safe_callable
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
ob
;
int
res
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
ob
))
return
NULL
;
res
=
safe_PyCallable_Check
(
ob
);
if
(
res
)
return
PyInt_FromLong
(
1
);
else
return
PyInt_FromLong
(
0
);
}
static
PyObject
*
_join_unicode
(
PyObject
*
prejoin
)
{
PyObject
*
joined
;
joined
=
PyObject_CallFunction
(
join
,
"OO"
,
prejoin
,
py_
);
if
(
!
joined
&&
PyErr_ExceptionMatches
(
PyExc_UnicodeError
))
{
int
i
,
l
;
PyObject
*
list
;
PyErr_Clear
();
list
=
PySequence_List
(
prejoin
);
if
(
!
list
)
{
return
NULL
;
}
l
=
PyList_Size
(
list
);
for
(
i
=
0
;
i
<
l
;
++
i
)
{
PyObject
*
item
=
PyList_GetItem
(
list
,
i
);
if
(
PyString_Check
(
item
))
{
PyObject
*
unicode
=
PyUnicode_DecodeLatin1
(
PyString_AsString
(
item
),
PyString_Size
(
item
),
NULL
);
if
(
unicode
)
{
PyList_SetItem
(
list
,
i
,
unicode
);
}
else
{
Py_DECREF
(
list
);
return
NULL
;
}
}
}
joined
=
PyObject_CallFunction
(
join
,
"OO"
,
list
,
py_
);
Py_DECREF
(
list
);
}
return
joined
;
}
static
PyObject
*
join_unicode
(
PyObject
*
self
,
PyObject
*
args
)
{
PyObject
*
ob
;
UNLESS
(
PyArg_ParseTuple
(
args
,
"O"
,
&
ob
))
return
NULL
;
return
_join_unicode
(
ob
);
}
static
struct
PyMethodDef
Module_Level__methods
[]
=
{
{
"render_blocks"
,
(
PyCFunction
)
render_blocks
,
METH_VARARGS
,
""
},
{
"join_unicode"
,
(
PyCFunction
)
join_unicode
,
METH_VARARGS
,
"join a list of plain strings into a single plain string,
\n
"
"a list of unicode strings into a single unicode strings,
\n
"
"or a list containing a mix into a single unicode string with
\n
"
"the plain strings converted from latin-1"
},
{
"safe_callable"
,
(
PyCFunction
)
safe_callable
,
METH_VARARGS
,
"callable() with a workaround for a problem with ExtensionClasses
\n
"
"and __call__()."
},
{
NULL
,
(
PyCFunction
)
NULL
,
0
,
NULL
}
/* sentinel */
};
void
initcDocumentTemplate
(
void
)
{
PyObject
*
m
,
*
d
;
DictInstanceType
.
ob_type
=&
PyType_Type
;
UNLESS
(
html_quote
=
PyImport_ImportModule
(
"DocumentTemplate.html_quote"
))
return
;
ASSIGN
(
ustr
,
PyObject_GetAttrString
(
html_quote
,
"ustr"
));
UNLESS
(
ustr
)
return
;
ASSIGN
(
html_quote
,
PyObject_GetAttrString
(
html_quote
,
"html_quote"
));
UNLESS
(
html_quote
)
return
;
UNLESS
(
py_isDocTemp
=
PyString_FromString
(
"isDocTemp"
))
return
;
UNLESS
(
py_renderNS
=
PyString_FromString
(
"__render_with_namespace__"
))
return
;
UNLESS
(
py_blocks
=
PyString_FromString
(
"blocks"
))
return
;
UNLESS
(
untaint_name
=
PyString_FromString
(
"__untaint__"
))
return
;
UNLESS
(
py_acquire
=
PyString_FromString
(
"aq_acquire"
))
return
;
UNLESS
(
py___call__
=
PyString_FromString
(
"__call__"
))
return
;
UNLESS
(
py___roles__
=
PyString_FromString
(
"__roles__"
))
return
;
UNLESS
(
py__proxy_roles
=
PyString_FromString
(
"_proxy_roles"
))
return
;
UNLESS
(
py_guarded_getattr
=
PyString_FromString
(
"guarded_getattr"
))
return
;
UNLESS
(
py__push
=
PyString_FromString
(
"_push"
))
return
;
UNLESS
(
py__pop
=
PyString_FromString
(
"_pop"
))
return
;
UNLESS
(
py_aq_base
=
PyString_FromString
(
"aq_base"
))
return
;
UNLESS
(
py_Unauthorized
=
PyString_FromString
(
"Unauthorized"
))
return
;
UNLESS
(
py_Unauthorized_fmt
=
PyString_FromString
(
"You are not authorized to access <em>%s</em>."
))
return
;
UNLESS
(
py___class__
=
PyString_FromString
(
"__class__"
))
return
;
UNLESS
(
py_AUTHENTICATED_USER
=
PyString_FromString
(
"AUTHENTICATED_USER"
))
return
;
UNLESS
(
py_
=
PyString_FromString
(
""
))
return
;
UNLESS
(
join
=
PyImport_ImportModule
(
"string"
))
return
;
ASSIGN
(
join
,
PyObject_GetAttrString
(
join
,
"join"
));
UNLESS
(
join
)
return
;
UNLESS
(
ExtensionClassImported
)
return
;
m
=
Py_InitModule4
(
"cDocumentTemplate"
,
Module_Level__methods
,
cDocumentTemplate_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
d
=
PyModule_GetDict
(
m
);
PyExtensionClass_Export
(
d
,
"InstanceDict"
,
InstanceDictType
);
PyExtensionClass_Export
(
d
,
"TemplateDict"
,
MMtype
);
}
src/DocumentTemplate/html_quote.py
deleted
100644 → 0
View file @
13bc9b23
# split off into its own module for aliasing without circrefs
from
cgi
import
escape
from
DocumentTemplate.ustr
import
ustr
def
html_quote
(
v
,
name
=
'(Unknown name)'
,
md
=
{}):
return
escape
(
ustr
(
v
),
1
)
src/DocumentTemplate/pDocumentTemplate.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Python implementations of document template some features
XXX This module is no longer actively used, but is left as an
XXX implementation reference for cDocumentTemplate
$Id$"""
__version__
=
'$Revision: 1.42 $'
[
11
:
-
2
]
import
sys
,
types
from
types
import
StringType
,
UnicodeType
,
TupleType
from
DocumentTemplate.ustr
import
ustr
import
warnings
warnings
.
warn
(
'pDocumentTemplate is not longer in active use. '
'It remains only as an implementation reference.'
,
DeprecationWarning
)
ClassTypes
=
[
types
.
ClassType
]
try
:
from
ExtensionClass
import
Base
except
ImportError
:
pass
else
:
class
c
(
Base
):
pass
ClassTypes
.
append
(
c
.
__class__
)
def
safe_callable
(
ob
):
# Works with ExtensionClasses and Acquisition.
if
hasattr
(
ob
,
'__class__'
):
if
hasattr
(
ob
,
'__call__'
):
return
1
else
:
return
type
(
ob
)
in
ClassTypes
else
:
return
callable
(
ob
)
class
InstanceDict
:
guarded_getattr
=
None
def
__init__
(
self
,
o
,
namespace
,
guarded_getattr
=
None
):
self
.
self
=
o
self
.
cache
=
{}
self
.
namespace
=
namespace
if
guarded_getattr
is
None
:
self
.
guarded_getattr
=
namespace
.
guarded_getattr
else
:
self
.
guarded_getattr
=
guarded_getattr
def
has_key
(
self
,
key
):
return
hasattr
(
self
.
self
,
key
)
def
keys
(
self
):
return
self
.
self
.
__dict__
.
keys
()
def
__repr__
(
self
):
return
'InstanceDict(%s)'
%
str
(
self
.
self
)
def
__getitem__
(
self
,
key
):
cache
=
self
.
cache
if
cache
.
has_key
(
key
):
return
cache
[
key
]
inst
=
self
.
self
if
key
[:
1
]
==
'_'
:
if
key
!=
'__str__'
:
raise
KeyError
,
key
# Don't divuldge private data
else
:
return
str
(
inst
)
get
=
self
.
guarded_getattr
if
get
is
None
:
get
=
getattr
try
:
r
=
get
(
inst
,
key
)
except
AttributeError
:
raise
KeyError
,
key
self
.
cache
[
key
]
=
r
return
r
def
__len__
(
self
):
return
1
class
MultiMapping
:
def
__init__
(
self
):
self
.
dicts
=
[]
def
__getitem__
(
self
,
key
):
for
d
in
self
.
dicts
:
try
:
return
d
[
key
]
except
(
KeyError
,
AttributeError
):
# XXX How do we get an AttributeError?
pass
raise
KeyError
,
key
def
push
(
self
,
d
):
self
.
dicts
.
insert
(
0
,
d
)
def
pop
(
self
,
n
=
1
):
r
=
self
.
dicts
[
-
1
]
del
self
.
dicts
[:
n
]
return
r
def
keys
(
self
):
kz
=
[]
for
d
in
self
.
dicts
:
kz
=
kz
+
d
.
keys
()
return
kz
class
DictInstance
:
def
__init__
(
self
,
mapping
):
self
.
__d
=
mapping
def
__getattr__
(
self
,
name
):
try
:
return
self
.
__d
[
name
]
except
KeyError
:
raise
AttributeError
,
name
class
TemplateDict
:
level
=
0
def
_pop
(
self
,
n
=
1
):
return
self
.
dicts
.
pop
(
n
)
def
_push
(
self
,
d
):
return
self
.
dicts
.
push
(
d
)
def
__init__
(
self
):
m
=
self
.
dicts
=
MultiMapping
()
self
.
_pop
=
m
.
pop
self
.
_push
=
m
.
push
try
:
self
.
keys
=
m
.
keys
except
:
pass
def
__getitem__
(
self
,
key
,
call
=
1
):
v
=
self
.
dicts
[
key
]
if
call
:
if
hasattr
(
v
,
'__render_with_namespace__'
):
return
v
.
__render_with_namespace__
(
self
)
vbase
=
getattr
(
v
,
'aq_base'
,
v
)
if
safe_callable
(
vbase
):
if
getattr
(
vbase
,
'isDocTemp'
,
0
):
v
=
v
(
None
,
self
)
else
:
v
=
v
()
return
v
def
__len__
(
self
):
total
=
0
for
d
in
self
.
dicts
.
dicts
:
total
=
total
+
len
(
d
)
return
total
def
has_key
(
self
,
key
):
try
:
v
=
self
.
dicts
[
key
]
except
KeyError
:
return
0
return
1
getitem
=
__getitem__
def
__call__
(
self
,
*
args
,
**
kw
):
if
args
:
if
len
(
args
)
==
1
and
not
kw
:
m
=
args
[
0
]
else
:
m
=
self
.
__class__
()
for
a
in
args
:
m
.
_push
(
a
)
if
kw
:
m
.
_push
(
kw
)
else
:
m
=
kw
return
(
DictInstance
(
m
),)
def
render_blocks
(
blocks
,
md
):
rendered
=
[]
append
=
rendered
.
append
for
section
in
blocks
:
if
type
(
section
)
is
TupleType
:
l
=
len
(
section
)
if
l
==
1
:
# Simple var
section
=
section
[
0
]
if
type
(
section
)
is
StringType
:
section
=
md
[
section
]
else
:
section
=
section
(
md
)
section
=
ustr
(
section
)
else
:
# if
cache
=
{}
md
.
_push
(
cache
)
try
:
i
=
0
m
=
l
-
1
while
i
<
m
:
cond
=
section
[
i
]
if
type
(
cond
)
is
StringType
:
n
=
cond
try
:
cond
=
md
[
cond
]
cache
[
n
]
=
cond
except
KeyError
,
v
:
v
=
str
(
v
)
if
n
!=
v
:
raise
KeyError
,
v
,
sys
.
exc_traceback
cond
=
None
else
:
cond
=
cond
(
md
)
if
cond
:
section
=
section
[
i
+
1
]
if
section
:
section
=
render_blocks
(
section
,
md
)
else
:
section
=
''
m
=
0
break
i
=
i
+
2
if
m
:
if
i
==
m
:
section
=
render_blocks
(
section
[
i
],
md
)
else
:
section
=
''
finally
:
md
.
_pop
()
elif
type
(
section
)
is
not
StringType
and
type
(
section
)
is
not
UnicodeType
:
section
=
section
(
md
)
if
section
:
rendered
.
append
(
section
)
l
=
len
(
rendered
)
if
l
==
0
:
return
''
elif
l
==
1
:
return
rendered
[
0
]
return
join_unicode
(
rendered
)
def
join_unicode
(
rendered
):
"""join a list of plain strings into a single plain string,
a list of unicode strings into a single unicode strings,
or a list containing a mix into a single unicode string with
the plain strings converted from latin-1
"""
try
:
return
''
.
join
(
rendered
)
except
UnicodeError
:
# A mix of unicode string and non-ascii plain strings.
# Fix up the list, treating normal strings as latin-1
rendered
=
list
(
rendered
)
for
i
in
range
(
len
(
rendered
)):
if
type
(
rendered
[
i
])
is
StringType
:
rendered
[
i
]
=
unicode
(
rendered
[
i
],
'latin-1'
)
return
u''
.
join
(
rendered
)
src/DocumentTemplate/permissions.py
deleted
100644 → 0
View file @
13bc9b23
change_dtml_documents
=
'Change DTML Documents'
change_dtml_methods
=
'Change DTML Methods'
src/DocumentTemplate/security.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Add security system support to Document Templates
"""
# Setup RestrictedDTML
from
AccessControl.ImplPython
import
guarded_getattr
from
AccessControl.ZopeGuards
import
guarded_getitem
RestrictedDTML
=
None
class
BaseRestrictedDTML
:
"""A mix-in for derivatives of DT_String.String that adds Zope security."""
def
guarded_getattr
(
self
,
*
args
):
# ob, name [, default]
return
guarded_getattr
(
*
args
)
def
guarded_getitem
(
self
,
ob
,
index
):
return
guarded_getitem
(
ob
,
index
)
# This does not respect the security policy as set by AccessControl. Instead
# it only deals with the C module being compiled or not.
try
:
from
AccessControl.cAccessControl
import
RestrictedDTMLMixin
except
ImportError
:
RestrictedDTML
=
BaseRestrictedDTML
else
:
class
RestrictedDTML
(
RestrictedDTMLMixin
,
BaseRestrictedDTML
):
"""C version of RestrictedDTML."""
# Add security testing capabilities
from
AccessControl
import
SecurityManagement
class
DTMLSecurityAPI
:
"""API for performing security checks in DTML using '_' methods.
"""
def
SecurityValidate
(
md
,
inst
,
parent
,
name
,
value
):
"""Validate access.
Arguments:
accessed -- the object that was being accessed
container -- the object the value was found in
name -- The name used to access the value
value -- The value retrieved though the access.
The arguments may be provided as keyword arguments. Some of these
arguments may be ommitted, however, the policy may reject access
in some cases when arguments are ommitted. It is best to provide
all the values possible.
"""
return
(
SecurityManagement
.
getSecurityManager
()
.
validate
(
inst
,
parent
,
name
,
value
)
)
def
SecurityCheckPermission
(
md
,
permission
,
object
):
"""Check whether the security context allows the given permission on
the given object.
Arguments:
permission -- A permission name
object -- The object being accessed according to the permission
"""
return
(
SecurityManagement
.
getSecurityManager
()
.
checkPermission
(
permission
,
object
)
)
def
SecurityGetUser
(
md
):
"""Gen the current authenticated user"""
return
(
SecurityManagement
.
getSecurityManager
()
.
getUser
()
)
def
SecurityCalledByExecutable
(
md
):
"""Return a boolean value indicating if this context was called
by an executable"""
r
=
(
SecurityManagement
.
getSecurityManager
()
.
calledByExecutable
()
)
if
r
>
0
:
return
r
-
1
return
r
from
DocumentTemplate
import
DT_Util
for
name
,
v
in
DTMLSecurityAPI
.
__dict__
.
items
():
if
name
[
0
]
!=
'_'
:
setattr
(
DT_Util
.
TemplateDict
,
name
,
v
)
from
types
import
FunctionType
from
AccessControl.ZopeGuards
import
safe_builtins
for
name
,
v
in
safe_builtins
.
items
():
if
type
(
v
)
is
FunctionType
:
v
=
DT_Util
.
NotBindable
(
v
)
if
name
.
startswith
(
'__'
):
continue
setattr
(
DT_Util
.
TemplateDict
,
name
,
v
)
# Temporarily create a DictInstance so that we can mark its type as
# being a key in the ContainerAssertions.
from
AccessControl.SimpleObjectPolicies
import
ContainerAssertions
class
_dummy_class
:
pass
templateDict
=
DT_Util
.
TemplateDict
()
try
:
dictInstance
=
templateDict
(
dummy
=
1
)[
0
]
if
type
(
dictInstance
)
is
not
type
(
_dummy_class
()):
ContainerAssertions
[
type
(
dictInstance
)]
=
1
except
:
# Hmm, this may cause _() and _.namespace() to fail.
# What to do?
pass
src/DocumentTemplate/sequence/SortEx.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
from
zope.sequencesort.ssort
import
*
src/DocumentTemplate/sequence/__init__.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
__allow_access_to_unprotected_subobjects__
=
1
from
zope.sequencesort.ssort
import
*
src/DocumentTemplate/sequence/tests/__init__.py
deleted
100644 → 0
View file @
13bc9b23
"""
Python package.
"""
src/DocumentTemplate/sequence/tests/results.py
deleted
100644 → 0
View file @
13bc9b23
res1
=
[{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
}]
res2
=
[{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
}]
res3
=
[{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
}]
res4
=
[{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
}]
res5
=
[{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
},
{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
}]
res6
=
[{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
}]
res7
=
[{
'weight'
:
-
1
,
'word'
:
'JJJ'
,
'key'
:
'jjj'
},
{
'weight'
:
-
1
,
'word'
:
'QQQ'
,
'key'
:
'qqq'
},
{
'weight'
:
-
1
,
'word'
:
'YYY'
,
'key'
:
'yyy'
},
{
'weight'
:
0
,
'word'
:
'BBB'
,
'key'
:
'bbb'
},
{
'weight'
:
0
,
'word'
:
'CCC'
,
'key'
:
'ccc'
},
{
'weight'
:
0
,
'word'
:
'DDD'
,
'key'
:
'ddd'
},
{
'weight'
:
0
,
'word'
:
'FFF'
,
'key'
:
'fff'
},
{
'weight'
:
0
,
'word'
:
'GGG'
,
'key'
:
'ggg'
},
{
'weight'
:
0
,
'word'
:
'HHH'
,
'key'
:
'hhh'
},
{
'weight'
:
0
,
'word'
:
'KKK'
,
'key'
:
'kkk'
},
{
'weight'
:
0
,
'word'
:
'LLL'
,
'key'
:
'lll'
},
{
'weight'
:
0
,
'word'
:
'MMM'
,
'key'
:
'mmm'
},
{
'weight'
:
0
,
'word'
:
'NNN'
,
'key'
:
'nnn'
},
{
'weight'
:
0
,
'word'
:
'PPP'
,
'key'
:
'ppp'
},
{
'weight'
:
0
,
'word'
:
'RRR'
,
'key'
:
'rrr'
},
{
'weight'
:
0
,
'word'
:
'SSS'
,
'key'
:
'sss'
},
{
'weight'
:
0
,
'word'
:
'TTT'
,
'key'
:
'ttt'
},
{
'weight'
:
0
,
'word'
:
'VVV'
,
'key'
:
'vvv'
},
{
'weight'
:
0
,
'word'
:
'WWW'
,
'key'
:
'www'
},
{
'weight'
:
0
,
'word'
:
'XXX'
,
'key'
:
'xxx'
},
{
'weight'
:
0
,
'word'
:
'ZZZ'
,
'key'
:
'zzz'
},
{
'weight'
:
1
,
'word'
:
'AAA'
,
'key'
:
'aaa'
},
{
'weight'
:
1
,
'word'
:
'EEE'
,
'key'
:
'eee'
},
{
'weight'
:
1
,
'word'
:
'III'
,
'key'
:
'iii'
},
{
'weight'
:
1
,
'word'
:
'OOO'
,
'key'
:
'ooo'
},
{
'weight'
:
1
,
'word'
:
'UUU'
,
'key'
:
'uuu'
}]
src/DocumentTemplate/sequence/tests/testSequence.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import
unittest
from
DocumentTemplate.sequence.SortEx
import
*
from
DocumentTemplate.sequence.tests.ztestlib
import
*
from
DocumentTemplate.sequence.tests.results
import
*
class
TestCase
(
unittest
.
TestCase
):
"""
Test SortEx .
"""
def
setUp
(
self
):
"""
"""
def
tearDown
(
self
):
"""
"""
def
test1
(
self
):
"test1"
assert
res1
==
SortEx
(
wordlist
)
def
test2
(
self
):
"test2"
assert
res2
==
SortEx
(
wordlist
,
((
"key"
,),),
mapping
=
1
)
def
test3
(
self
):
"test3"
assert
res3
==
SortEx
(
wordlist
,
((
"key"
,
"cmp"
),),
mapping
=
1
)
def
test4
(
self
):
"test4"
assert
res4
==
SortEx
(
wordlist
,
((
"key"
,
"cmp"
,
"desc"
),),
mapping
=
1
)
def
test5
(
self
):
"test5"
assert
res5
==
SortEx
(
wordlist
,
((
"weight"
,),
(
"key"
,)),
mapping
=
1
)
def
test6
(
self
):
"test6"
assert
res6
==
SortEx
(
wordlist
,
((
"weight"
,),
(
"key"
,
"nocase"
,
"desc"
)),
mapping
=
1
)
def
test7
(
self
):
"test7"
def
myCmp
(
s1
,
s2
):
return
-
cmp
(
s1
,
s2
)
# Create namespace...
from
DocumentTemplate.DT_Util
import
TemplateDict
md
=
TemplateDict
()
#... and push out function onto the namespace
md
.
_push
({
"myCmp"
:
myCmp
})
assert
res7
==
SortEx
(
wordlist
,
(
(
"weight"
,)
,
(
"key"
,
"myCmp"
,
"desc"
)
)
,
md
,
mapping
=
1
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
TestCase
)
)
return
suite
def
main
():
unittest
.
TextTestRunner
().
run
(
test_suite
())
if
__name__
==
'__main__'
:
main
()
src/DocumentTemplate/sequence/tests/ztestlib.py
deleted
100644 → 0
View file @
13bc9b23
class
standard_html
:
# Base class for using with ZTemplates
def
__init__
(
self
,
title
):
self
.
standard_html_header
=
"""<HTML>
<HEAD>
<TITLE>
%s
</TITLE>
</HEAD>
<BODY>"""
%
title
self
.
standard_html_footer
=
"""</BODY>
</HTML>"""
self
.
title
=
title
def
test
(
s
):
outfile
=
open
(
"test.out"
,
'w'
)
outfile
.
write
(
s
)
outfile
.
close
()
def
exception
():
import
sys
,
traceback
exc_type
,
exc_value
,
exc_tb
=
sys
.
exc_info
()
outfile
=
open
(
"test.err"
,
'w'
)
traceback
.
print_exception
(
exc_type
,
exc_value
,
exc_tb
,
None
,
outfile
)
outfile
.
close
()
wordlist
=
[
{
"key"
:
"aaa"
,
"word"
:
"AAA"
,
"weight"
:
1
},
{
"key"
:
"bbb"
,
"word"
:
"BBB"
,
"weight"
:
0
},
{
"key"
:
"ccc"
,
"word"
:
"CCC"
,
"weight"
:
0
},
{
"key"
:
"ddd"
,
"word"
:
"DDD"
,
"weight"
:
0
},
{
"key"
:
"eee"
,
"word"
:
"EEE"
,
"weight"
:
1
},
{
"key"
:
"fff"
,
"word"
:
"FFF"
,
"weight"
:
0
},
{
"key"
:
"ggg"
,
"word"
:
"GGG"
,
"weight"
:
0
},
{
"key"
:
"hhh"
,
"word"
:
"HHH"
,
"weight"
:
0
},
{
"key"
:
"iii"
,
"word"
:
"III"
,
"weight"
:
1
},
{
"key"
:
"jjj"
,
"word"
:
"JJJ"
,
"weight"
:
-
1
},
{
"key"
:
"kkk"
,
"word"
:
"KKK"
,
"weight"
:
0
},
{
"key"
:
"lll"
,
"word"
:
"LLL"
,
"weight"
:
0
},
{
"key"
:
"mmm"
,
"word"
:
"MMM"
,
"weight"
:
0
},
{
"key"
:
"nnn"
,
"word"
:
"NNN"
,
"weight"
:
0
},
{
"key"
:
"ooo"
,
"word"
:
"OOO"
,
"weight"
:
1
},
{
"key"
:
"ppp"
,
"word"
:
"PPP"
,
"weight"
:
0
},
{
"key"
:
"qqq"
,
"word"
:
"QQQ"
,
"weight"
:
-
1
},
{
"key"
:
"rrr"
,
"word"
:
"RRR"
,
"weight"
:
0
},
{
"key"
:
"sss"
,
"word"
:
"SSS"
,
"weight"
:
0
},
{
"key"
:
"ttt"
,
"word"
:
"TTT"
,
"weight"
:
0
},
{
"key"
:
"uuu"
,
"word"
:
"UUU"
,
"weight"
:
1
},
{
"key"
:
"vvv"
,
"word"
:
"VVV"
,
"weight"
:
0
},
{
"key"
:
"www"
,
"word"
:
"WWW"
,
"weight"
:
0
},
{
"key"
:
"xxx"
,
"word"
:
"XXX"
,
"weight"
:
0
},
{
"key"
:
"yyy"
,
"word"
:
"YYY"
,
"weight"
:
-
1
},
{
"key"
:
"zzz"
,
"word"
:
"ZZZ"
,
"weight"
:
0
}
]
src/DocumentTemplate/tests/__init__.py
deleted
100644 → 0
View file @
13bc9b23
'''
Python package.
'''
src/DocumentTemplate/tests/dealers.dtml
deleted
100644 → 0
View file @
13bc9b23
<html><head><title>
Inventory by Dealer
</title></head><body>
<dl>
<dtml-in
inventory
mapping
size=
5
start=
first_ad
orphan=
3
>
<dtml-if
previous-sequence
>
<dtml-in
previous-batches
mapping
>
(
<dtml-var
batch-start-var-dealer
>
<dtml-var
batch-start-var-year
>
<dtml-var
batch-start-var-make
>
<dtml-var
batch-start-var-model
>
-
<dtml-var
batch-end-var-dealer
>
<dtml-var
batch-end-var-year
>
<dtml-var
batch-end-var-make
>
<dtml-var
batch-end-var-model
>
)
</dtml-in
previous-batches
>
</dtml-if
previous-sequence
>
<dtml-if
first-dealer
>
<dt><dtml-var
dealer
></dt><dd>
</dtml-if
first-dealer
>
<dtml-var
year
>
<dtml-var
make
>
<dtml-var
model
>
<p>
<dtml-if
last-dealer
>
</dd>
</dtml-if
last-dealer
>
<dtml-if
next-sequence
>
<dtml-in
next-batches
mapping
>
(
<dtml-var
batch-start-var-dealer
>
<dtml-var
batch-start-var-year
>
<dtml-var
batch-start-var-make
>
<dtml-var
batch-start-var-model
>
-
<dtml-var
batch-end-var-dealer
>
<dtml-var
batch-end-var-year
>
<dtml-var
batch-end-var-make
>
<dtml-var
batch-end-var-model
>
)
</dtml-in
next-batches
>
</dtml-if
next-sequence
>
</dtml-in
inventory
>
</dl>
</body></html>
src/DocumentTemplate/tests/dealers.out
deleted
100644 → 0
View file @
13bc9b23
<html><head><title>
Inventory by Dealer
</title></head><body>
<dl>
(Bay Chevy 96 Chevrolet Caprice - Bay Chevy 96 Chevrolet Nova)
(Bay Chevy 96 Chevrolet Corvett - Bay Chevy 96 Chevrolet Corsica)
(Bay Chevy 96 Chevrolet Corsica - Colman Olds 96 Olds Ciera)
<dt>
Colman Olds
</dt><dd>
96 Olds Cutlass
<p>
95 Olds Cutlas
<p>
93 Dodge Shadow
<p>
94 Jeep Cheroke
<p>
92 Toyota Previa
<p>
</dd>
(Colman Olds 93 Toyota Celica - Colman Olds 94 Honda Civic)
(Colman Olds 93 Honda Civix - Spam Chev 96 Chevrolet Nova)
(Spam Chev 96 Chevrolet Corvett - Spam Chev 96 Chevrolet Corsica)
(Spam Chev 96 Chevrolet Corsica - Spam Olds 96 Olds Ciera)
(Spam Olds 96 Olds Cutlass - Spam Olds 92 Toyota Previa)
(Spam Olds 93 Toyota Celica - Spam Olds 93 Honda Civix)
</dl>
</body></html>
src/DocumentTemplate/tests/testDTML.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Document Template Tests
"""
import
unittest
class
DTMLTests
(
unittest
.
TestCase
):
def
_get_doc_class
(
self
):
from
DocumentTemplate.DT_HTML
import
HTML
return
HTML
doc_class
=
property
(
_get_doc_class
,)
def
testBatchingEtc
(
self
):
def
item
(
key
,
**
kw
):
return
(
key
,
kw
)
items
=
(
item
(
1
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Caprice'
,
year
=
96
),
item
(
2
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
4
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
5
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
3
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Corvett'
,
year
=
96
),
item
(
6
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
96
),
item
(
7
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
96
),
item
(
8
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
95
),
item
(
9
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Corsica'
,
year
=
96
),
item
(
10
,
dealer
=
'Bay Chevy'
,
make
=
'Chevrolet'
,
model
=
'Corsica'
,
year
=
96
),
item
(
11
,
dealer
=
'Bay Chevy'
,
make
=
'Toyota'
,
model
=
'Camry'
,
year
=
95
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Olds'
,
model
=
'Cutlass'
,
year
=
96
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Olds'
,
model
=
'Cutlas'
,
year
=
95
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Dodge'
,
model
=
'Shadow'
,
year
=
93
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Jeep'
,
model
=
'Cheroke'
,
year
=
94
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Toyota'
,
model
=
'Previa'
,
year
=
92
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Toyota'
,
model
=
'Celica'
,
year
=
93
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Toyota'
,
model
=
'Camry'
,
year
=
93
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Honda'
,
model
=
'Accord'
,
year
=
94
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Honda'
,
model
=
'Accord'
,
year
=
92
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Honda'
,
model
=
'Civic'
,
year
=
94
),
item
(
12
,
dealer
=
'Colman Olds'
,
make
=
'Honda'
,
model
=
'Civix'
,
year
=
93
),
item
(
1
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Caprice'
,
year
=
96
),
item
(
2
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
4
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
5
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Nova'
,
year
=
96
),
item
(
3
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Corvett'
,
year
=
96
),
item
(
6
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
96
),
item
(
7
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
96
),
item
(
8
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Lumina'
,
year
=
95
),
item
(
9
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Corsica'
,
year
=
96
),
item
(
10
,
dealer
=
'Spam Chev'
,
make
=
'Chevrolet'
,
model
=
'Corsica'
,
year
=
96
),
item
(
11
,
dealer
=
'Spam Chevy'
,
make
=
'Toyota'
,
model
=
'Camry'
,
year
=
95
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Olds'
,
model
=
'Ciera'
,
year
=
96
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Olds'
,
model
=
'Cutlass'
,
year
=
96
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Olds'
,
model
=
'Cutlas'
,
year
=
95
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Dodge'
,
model
=
'Shadow'
,
year
=
93
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Jeep'
,
model
=
'Cheroke'
,
year
=
94
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Toyota'
,
model
=
'Previa'
,
year
=
92
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Toyota'
,
model
=
'Celica'
,
year
=
93
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Toyota'
,
model
=
'Camry'
,
year
=
93
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Honda'
,
model
=
'Accord'
,
year
=
94
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Honda'
,
model
=
'Accord'
,
year
=
92
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Honda'
,
model
=
'Civic'
,
year
=
94
),
item
(
12
,
dealer
=
'Spam Olds'
,
make
=
'Honda'
,
model
=
'Civix'
,
year
=
93
),
)
html
=
self
.
doc_class
(
read_file
(
'dealers.dtml'
))
res
=
html
(
inventory
=
items
,
first_ad
=
15
)
expected
=
read_file
(
'dealers.out'
)
self
.
assertEqual
(
res
,
expected
)
def
testSequenceSummaries
(
self
):
data
=
(
dict
(
name
=
'jim'
,
age
=
38
),
# dict(name='kak', age=40),
dict
(
name
=
'will'
,
age
=
7
),
dict
(
name
=
'drew'
,
age
=
4
),
dict
(
name
=
'ches'
,
age
=
1
),
)
html
=
self
.
doc_class
(
'<dtml-in data mapping>'
'<dtml-if sequence-end>'
'Variable "name": '
'min=<dtml-var min-name> '
'max=<dtml-var max-name> '
'count=<dtml-var count-name> '
'total=<dtml-var total-name> '
'median=<dtml-var median-name> '
'Variable "age": '
'min=<dtml-var min-age> '
'max=<dtml-var max-age> '
'count=<dtml-var count-age> '
'total=<dtml-var total-age> '
'median=<dtml-var median-age> '
'mean=<dtml-var mean-age> '
'<dtml-let sda=standard-deviation-age>'
's.d.=<dtml-var expr="_.int(sda)">'
'</dtml-let>'
'</dtml-if sequence-end>'
'</dtml-in data>'
)
res
=
html
(
data
=
data
)
expected
=
(
'Variable "name": min=ches max=will count=4 total= '
'median=between jim and drew '
'Variable "age": min=1 max=38 count=4 total=50 '
'median=5 mean=12.5 s.d.=17'
)
assert
res
==
expected
,
res
def
testDTMLDateFormatting
(
self
):
import
DateTime
html
=
self
.
doc_class
(
"<dtml-var name capitalize spacify> is "
"<dtml-var date fmt=year>/<dtml-var date "
"fmt=month>/<dtml-var date fmt=day>"
)
res
=
html
(
date
=
DateTime
.
DateTime
(
"1995-12-25"
),
name
=
'christmas_day'
)
expected
=
'Christmas day is 1995/12/25'
assert
res
==
expected
,
res
def
testSimpleString
(
self
):
from
DocumentTemplate.DT_HTML
import
String
dt
=
String
(
'%(name)s'
)
res
=
dt
(
name
=
'Chris'
)
expected
=
'Chris'
assert
res
==
expected
,
res
def
testStringDateFormatting
(
self
):
import
DateTime
from
DocumentTemplate.DT_HTML
import
String
html
=
String
(
"%(name capitalize spacify)s is "
"%(date fmt=year)s/%(date fmt=month)s/%(date fmt=day)s"
)
res
=
html
(
date
=
DateTime
.
DateTime
(
"2001-04-27"
),
name
=
'the_date'
)
expected
=
'The date is 2001/4/27'
assert
res
==
expected
,
res
def
testSequence1
(
self
):
html
=
self
.
doc_class
(
'<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item> '
'</dtml-in sequence-item></dtml-in spam>'
)
expected
=
'1 2 3 4 5 6 '
res
=
html
(
spam
=
[[
1
,
2
,
3
],[
4
,
5
,
6
]])
assert
res
==
expected
,
res
def
testSequence2
(
self
):
html
=
self
.
doc_class
(
'<dtml-in spam><dtml-in sequence-item><dtml-var sequence-item>-'
'</dtml-in sequence-item></dtml-in spam>'
)
expected
=
'1-2-3-4-5-6-'
res
=
html
(
spam
=
[[
1
,
2
,
3
],[
4
,
5
,
6
]])
assert
res
==
expected
,
res
def
testNull
(
self
):
html
=
self
.
doc_class
(
'<dtml-var spam fmt="$%.2f bobs your uncle" '
'null="spam%eggs!|">'
)
expected
=
'$42.00 bobs your unclespam%eggs!|'
res
=
html
(
spam
=
42
)
+
html
(
spam
=
None
)
assert
res
==
expected
,
res
def
testUrlUnquote
(
self
):
html1
=
self
.
doc_class
(
"""
<dtml-var expr="'http%3A//www.zope.org%3Fa%3Db%20123'" fmt=url-unquote>
"""
)
html2
=
self
.
doc_class
(
"""
<dtml-var expr="'http%3A%2F%2Fwww.zope.org%3Fa%3Db+123'" fmt=url-unquote-plus>
"""
)
expected
=
(
"""
http://www.zope.org?a=b 123
"""
)
self
.
assertEqual
(
html1
(),
expected
)
self
.
assertEqual
(
html2
(),
expected
)
html1
=
self
.
doc_class
(
"""
<dtml-var expr="'http%3A//www.zope.org%3Fa%3Db%20123'" url_unquote>
"""
)
html2
=
self
.
doc_class
(
"""
<dtml-var expr="'http%3A%2F%2Fwww.zope.org%3Fa%3Db+123'" url_unquote_plus>
"""
)
expected
=
(
"""
http://www.zope.org?a=b 123
"""
)
self
.
assertEqual
(
html1
(),
expected
)
self
.
assertEqual
(
html2
(),
expected
)
def
test_fmt
(
self
):
html
=
self
.
doc_class
(
"""
<dtml-var spam>
html=<dtml-var spam fmt=html-quote>
url=<dtml-var spam fmt=url-quote>
multi=<dtml-var spam fmt=multi-line>
dollars=<dtml-var spam fmt=whole-dollars>
cents=<dtml-var spam fmt=dollars-and-cents>
dollars,=<dtml-var spam fmt=dollars-with-commas>
cents,=<dtml-var spam fmt=dollars-and-cents-with-commas>"""
)
expected
=
(
'''
4200000
html=4200000
url=4200000
multi=4200000
dollars=$4200000
cents=$4200000.00
dollars,=$4,200,000
cents,=$4,200,000.00
None
html=None
url=None
multi=None
dollars=
cents=
dollars,=
cents,=
<a href="spam">
foo bar
html=<a href="spam">
foo bar
url=%3Ca%20href%3D%22spam%22%3E%0Afoo%20bar
multi=<a href="spam"><br />
foo bar
dollars=
cents=
dollars,=
cents,='''
)
res
=
html
(
spam
=
4200000
)
+
html
(
spam
=
None
)
+
html
(
spam
=
'<a href="spam">
\
n
foo bar'
)
self
.
assertEqual
(
res
,
expected
)
def
test_fmt_reST_include_directive_raises
(
self
):
source
=
'.. include:: /etc/passwd'
html
=
self
.
doc_class
(
'<dtml-var name="foo" fmt="restructured-text">'
)
html
.
_vars
[
'foo'
]
=
source
result
=
html
()
# The include: directive hasn't been rendered, it remains
# verbatimly in the rendered output. Instead a warning
# message is presented:
self
.
assert_
(
source
in
result
)
self
.
assert_
(
docutils_include_warning
in
result
)
def
test_fmt_reST_raw_directive_disabled
(
self
):
from
cgi
import
escape
EXPECTED
=
'<h1>HELLO WORLD</h1>'
source
=
'.. raw:: html
\
n
\
n
%s
\
n
'
%
EXPECTED
html
=
self
.
doc_class
(
'<dtml-var name="foo" fmt="restructured-text">'
)
html
.
_vars
[
'foo'
]
=
source
result
=
html
()
# The raw: directive hasn't been rendered, it remains
# verbatimly in the rendered output. Instead a warning
# message is presented:
self
.
assert_
(
EXPECTED
not
in
result
)
self
.
assert_
(
escape
(
EXPECTED
)
in
result
)
self
.
assert_
(
docutils_raw_warning
in
result
)
def
test_fmt_reST_raw_directive_file_option_raises
(
self
):
source
=
'.. raw:: html
\
n
:file: inclusion.txt'
html
=
self
.
doc_class
(
'<dtml-var name="foo" fmt="restructured-text">'
)
html
.
_vars
[
'foo'
]
=
source
result
=
html
()
# The raw: directive hasn't been rendered, it remains
# verbatimly in the rendered output. Instead a warning
# message is presented:
self
.
assert_
(
source
in
result
)
self
.
assert_
(
docutils_raw_warning
in
result
)
def
test_fmt_reST_raw_directive_url_option_raises
(
self
):
source
=
'.. raw:: html
\
n
:url: http://www.zope.org'
html
=
self
.
doc_class
(
'<dtml-var name="foo" fmt="restructured-text">'
)
html
.
_vars
[
'foo'
]
=
source
result
=
html
()
# The raw: directive hasn't been rendered, it remains
# verbatimly in the rendered output. Instead a warning
# message is presented:
self
.
assert_
(
source
in
result
)
self
.
assert_
(
docutils_raw_warning
in
result
)
def
testPropogatedError
(
self
):
from
ExtensionClass
import
Base
class
foo
:
def
__len__
(
self
):
return
9
def
__getitem__
(
self
,
i
):
if
i
>=
9
:
raise
IndexError
,
i
return
self
.
testob
(
i
)
class
testob
(
Base
):
__roles__
=
None
# Public
def
__init__
(
self
,
index
):
self
.
index
=
index
self
.
value
=
'item %s'
%
index
getValue__roles__
=
None
# Public
def
getValue
(
self
):
return
self
.
value
puke__roles__
=
None
# Public
def
puke
(
self
):
raise
PukeError
(
'raaalf'
)
html
=
self
.
doc_class
(
"""
<dtml-if spam>
<dtml-in spam>
<dtml-var getValue>
<dtml-var puke>
</dtml-in spam>
</dtml-if spam>
"""
)
try
:
html
(
spam
=
foo
())
except
PukeError
:
# Passed the test.
pass
else
:
assert
0
,
'Puke error not propogated'
def
testRenderCallable
(
self
):
#Test automatic rendering of callable objects
from
ExtensionClass
import
Base
class
C
(
Base
):
__allow_access_to_unprotected_subobjects__
=
1
x
=
1
def
y
(
self
):
return
self
.
x
*
2
C
.
h
=
self
.
doc_class
(
"The h method, <dtml-var x> <dtml-var y>"
)
C
.
h2
=
self
.
doc_class
(
"The h2 method"
)
expected
=
"1, 2, The h method, 1 2"
res
=
self
.
doc_class
(
"<dtml-var x>, <dtml-var y>, <dtml-var h>"
)(
C
())
assert
res
==
expected
,
res
expected
=
(
'''
1,
2,
The h2 method'''
)
res
=
self
.
doc_class
(
'''
<dtml-var expr="_.render(i.x)">,
<dtml-var expr="_.render(i.y)">,
<dtml-var expr="_.render(i.h2)">'''
)(
i
=
C
())
assert
res
==
expected
,
res
def
testWith
(
self
):
class
person
:
__allow_access_to_unprotected_subobjects__
=
1
name
=
'Jim'
height_inches
=
73
expected
=
'Hi, my name is %s and my height is %d cm.'
%
(
person
.
name
,
int
(
person
.
height_inches
*
2.54
))
res
=
self
.
doc_class
(
'<dtml-with person>Hi, my name is <dtml-var name> '
'and my height is <dtml-var "_.int(height_inches*2.54)"> '
'cm.</dtml-with>'
)(
person
=
person
)
assert
res
==
expected
,
res
def
testRaise
(
self
):
try
:
res
=
self
.
doc_class
(
"<dtml-raise IndexError>success!</dtml-raise>"
)()
except
IndexError
,
v
:
res
=
v
assert
str
(
res
)
==
'success!'
,
`res`
def
testNoItemPush
(
self
):
data
=
dict
(
sec
=
'B'
,
name
=
'XXX'
,
sub
=
(
dict
(
name
=
'b1'
),
dict
(
name
=
'b2'
,
sec
=
'XXX'
)))
html
=
"""
<dtml-with data mapping><dtml-in sub no_push_item>
<dtml-var sec>.<dtml-with sequence-item mapping><dtml-var name></dtml-with>
</dtml-in></dtml-with>
"""
expected
=
"""
B.b1 B.b2"""
result
=
self
.
doc_class
(
html
)(
data
=
data
)
assert
result
==
expected
,
result
def
testBasicHTMLIn
(
self
):
data
=
(
dict
(
name
=
'jim'
,
age
=
39
),
dict
(
name
=
'kak'
,
age
=
29
),
dict
(
name
=
'will'
,
age
=
8
),
dict
(
name
=
'andrew'
,
age
=
5
),
dict
(
name
=
'chessie'
,
age
=
2
),
)
html
=
"""
<!--#in data mapping-->
<!--#var name-->, <!--#var age-->
<!--#/in-->
"""
expected
=
"""
jim, 39
kak, 29
will, 8
andrew, 5
chessie, 2
"""
result
=
self
.
doc_class
(
html
)(
data
=
data
)
assert
result
==
expected
,
result
def
testBasicHTMLIn2
(
self
):
xxx
=
(
Dummy
(
name
=
1
),
Dummy
(
name
=
2
),
Dummy
(
name
=
3
))
html
=
"""
<!--#in xxx-->
<!--#var name -->
<!--#/in-->
"""
expected
=
"""
1
2
3
"""
result
=
self
.
doc_class
(
html
)(
xxx
=
xxx
)
assert
result
==
expected
,
result
def
testBasicHTMLIn3
(
self
):
ns
=
{
'prop_ids'
:
(
'title'
,
'id'
),
'title'
:
'good'
,
'id'
:
'times'
}
html
=
""":<dtml-in prop_ids><dtml-var sequence-item>=<dtml-var
expr="_[_['sequence-item']]">:</dtml-in>"""
result
=
self
.
doc_class
(
html
)(
None
,
ns
)
expected
=
":title=good:id=times:"
assert
result
==
expected
,
result
def
testHTMLInElse
(
self
):
xxx
=
(
Dummy
(
name
=
1
),
Dummy
(
name
=
2
),
Dummy
(
name
=
3
))
html
=
"""
<!--#in data mapping-->
<!--#var name-->, <!--#var age-->
<!--#else-->
<!--#in xxx-->
<!--#var name -->
<!--#/in-->
<!--#/in-->
"""
expected
=
"""
1
2
3
"""
result
=
self
.
doc_class
(
html
)(
xxx
=
xxx
,
data
=
{})
assert
result
==
expected
,
result
def
testBasicStringIn
(
self
):
from
DocumentTemplate.DT_HTML
import
String
data
=
(
dict
(
name
=
'jim'
,
age
=
39
),
dict
(
name
=
'kak'
,
age
=
29
),
dict
(
name
=
'will'
,
age
=
8
),
dict
(
name
=
'andrew'
,
age
=
5
),
dict
(
name
=
'chessie'
,
age
=
2
),
)
s
=
"""
%(in data mapping)[
%(name)s, %(age)s
%(in)]
"""
expected
=
"""
jim, 39
kak, 29
will, 8
andrew, 5
chessie, 2
"""
result
=
String
(
s
)(
data
=
data
)
assert
expected
==
result
,
result
def
read_file
(
name
):
import
os
from
DocumentTemplate
import
tests
here
=
tests
.
__path__
[
0
]
f
=
open
(
os
.
path
.
join
(
here
,
name
),
'r'
)
res
=
f
.
read
()
f
.
close
()
return
res
class
Dummy
:
__allow_access_to_unprotected_subobjects__
=
1
def
__init__
(
self
,
**
kw
):
self
.
__dict__
.
update
(
kw
)
def
__repr__
(
self
):
return
"Dummy(%s)"
%
`self.__dict__`
docutils_include_warning
=
'''
\
<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils"><string></tt>, line 1)</p>
<p>"include" directive disabled.</p>'''
docutils_raw_warning
=
'''
\
<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils"><string></tt>, line 1)</p>
<p>"raw" directive disabled.</p>'''
class
PukeError
(
Exception
):
"""Exception raised in test code."""
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
DTMLTests
)
)
return
suite
src/DocumentTemplate/tests/testDTMLUnicode.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Document Template Tests
"""
import
unittest
class
force_str
:
# A class whose string representation is not always a plain string:
def
__init__
(
self
,
s
):
self
.
s
=
s
def
__str__
(
self
):
return
self
.
s
class
DTMLUnicodeTests
(
unittest
.
TestCase
):
def
_get_doc_class
(
self
):
from
DocumentTemplate.DT_HTML
import
HTML
return
HTML
doc_class
=
property
(
_get_doc_class
,)
def
testAA
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
'helloworld'
res
=
html
(
a
=
'hello'
,
b
=
'world'
)
assert
res
==
expected
,
`res`
def
testUU
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
u'helloworld'
res
=
html
(
a
=
u'hello'
,
b
=
u'world'
)
assert
res
==
expected
,
`res`
def
testAU
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
u'helloworld'
res
=
html
(
a
=
'hello'
,
b
=
u'world'
)
assert
res
==
expected
,
`res`
def
testAB
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
'hello
\
xc8
'
res
=
html
(
a
=
'hello'
,
b
=
chr
(
200
))
assert
res
==
expected
,
`res`
def
testUB
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
u'hello
\
xc8
'
res
=
html
(
a
=
u'hello'
,
b
=
chr
(
200
))
assert
res
==
expected
,
`res`
def
testUB2
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
u'
\
u07d0
\
xc8
'
res
=
html
(
a
=
unichr
(
2000
),
b
=
chr
(
200
))
assert
res
==
expected
,
`res`
def
testUnicodeStr
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a><dtml-var b>'
)
expected
=
u'
\
u07d0
\
xc8
'
res
=
html
(
a
=
force_str
(
unichr
(
2000
)),
b
=
chr
(
200
))
assert
res
==
expected
,
`res`
def
testUqB
(
self
):
html
=
self
.
doc_class
(
'<dtml-var a html_quote><dtml-var b>'
)
expected
=
u'he>llo
\
xc8
'
res
=
html
(
a
=
u'he>llo'
,
b
=
chr
(
200
))
assert
res
==
expected
,
`res`
def
testSize
(
self
):
html
=
self
.
doc_class
(
'<dtml-var "_.unichr(200)*4" size=2>'
)
expected
=
unichr
(
200
)
*
2
+
'...'
res
=
html
()
assert
res
==
expected
,
`res`
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
DTMLUnicodeTests
)
)
return
suite
src/DocumentTemplate/tests/testSecurity.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Document Template Tests
"""
import
unittest
from
DocumentTemplate
import
HTML
from
DocumentTemplate.tests.testDTML
import
DTMLTests
from
DocumentTemplate.security
import
RestrictedDTML
from
AccessControl
import
Unauthorized
from
AccessControl.SecurityManagement
import
getSecurityManager
from
ExtensionClass
import
Base
class
UnownedDTML
(
RestrictedDTML
,
HTML
):
def
getOwner
(
self
):
return
None
def
__call__
(
self
,
client
=
None
,
REQUEST
=
{},
RESPONSE
=
None
,
**
kw
):
"""Render the DTML"""
security
=
getSecurityManager
()
security
.
addContext
(
self
)
try
:
return
HTML
.
__call__
(
self
,
client
,
REQUEST
,
**
kw
)
finally
:
security
.
removeContext
(
self
)
class
SecurityTests
(
DTMLTests
):
doc_class
=
UnownedDTML
unrestricted_doc_class
=
HTML
def
testNoImplicitAccess
(
self
):
class
person
:
name
=
'Jim'
doc
=
self
.
doc_class
(
'<dtml-with person>Hi, my name is '
'<dtml-var name></dtml-with>'
)
try
:
doc
(
person
=
person
())
except
Unauthorized
:
# Passed the test.
pass
else
:
assert
0
,
'Did not protect class instance'
def
testExprExplicitDeny
(
self
):
class
myclass
(
Base
):
__roles__
=
None
# Public
somemethod__roles__
=
()
# Private
def
somemethod
(
self
):
return
"This is a protected operation of public object"
html
=
self
.
doc_class
(
'<dtml-var expr="myinst.somemethod()">'
)
self
.
failUnlessRaises
(
Unauthorized
,
html
,
myinst
=
myclass
())
def
testSecurityInSyntax
(
self
):
# Ensures syntax errors are thrown for an expr with restricted
# syntax.
expr
=
'<dtml-var expr="(lambda x, _read=(lambda ob:ob): x.y)(c)">'
try
:
# This would be a security hole.
html
=
self
.
doc_class
(
expr
)
# It might compile here...
html
()
# or it might compile here.
except
SyntaxError
:
# Passed the test.
pass
else
:
assert
0
,
'Did not catch bad expr'
# Now be sure the syntax error occurred for security purposes.
html
=
self
.
unrestricted_doc_class
(
expr
)
class
c
:
y
=
10
res
=
html
(
c
=
c
)
assert
res
==
'10'
,
res
def
testNewDTMLBuiltins
(
self
):
NEW_BUILTINS_TEMPLATE
=
"""
<dtml-var expr="_.min([1,2])">
<dtml-var expr="_.max([2,3])">
<dtml-var expr="_.sum([1,2,3,4])">
<dtml-var expr="_.hasattr(1, 'foo') and 'Yes' or 'No'">
<dtml-var expr="_.None">
<dtml-var expr="_.string.strip(' testing ')">
<dtml-var expr="[x for x in (1, 2, 3)]">
"""
EXPECTED
=
[
'1'
,
'3'
,
'10'
,
'No'
,
'None'
,
'testing'
,
'[1, 2, 3]'
]
#
# XXX: these expressions seem like they should work, with
# the following ExPECTED, but they raise Unauthorized
# on the 'next' name.
#
#<dtml-var expr="_.iter([1,2,3]).next()">
#<dtml-var expr="_.enumerate([1,2,3]).next()">
#
#EXPECTED = ['1', '3', '10', '1', '(0, 1)']
template
=
self
.
doc_class
(
NEW_BUILTINS_TEMPLATE
)
res
=
template
()
lines
=
filter
(
None
,
[
x
.
strip
()
for
x
in
res
.
split
(
'
\
n
'
)])
self
.
assertEqual
(
lines
,
EXPECTED
)
# Note: we need more tests!
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
SecurityTests
))
return
suite
src/DocumentTemplate/tests/test_DT_Raise.py
deleted
100644 → 0
View file @
13bc9b23
import
unittest
class
Test_Raise
(
unittest
.
TestCase
):
def
_getTargetClass
(
self
):
from
DocumentTemplate.DT_Raise
import
Raise
return
Raise
def
_makeOne
(
self
,
type
=
None
,
expr
=
None
):
args
=
[]
if
type
is
not
None
:
args
.
append
(
'type="%s"'
%
type
)
if
expr
is
not
None
:
args
.
append
(
'expr="%s"'
%
expr
)
blocks
=
[(
'raise'
,
' '
.
join
(
args
),
DummySection
())]
return
self
.
_getTargetClass
()(
blocks
)
def
test_ctor_w_type
(
self
):
raiser
=
self
.
_makeOne
(
type
=
'Redirect'
)
self
.
assertEqual
(
raiser
.
__name__
,
'Redirect'
)
self
.
assertEqual
(
raiser
.
expr
,
None
)
def
test_ctor_w_expr
(
self
):
raiser
=
self
.
_makeOne
(
expr
=
'SyntaxError'
)
self
.
assertEqual
(
raiser
.
__name__
,
'SyntaxError'
)
self
.
assertEqual
(
raiser
.
expr
.
expr
,
'SyntaxError'
)
def
test_render_w_type_builtin_exception
(
self
):
from
DocumentTemplate.DT_Util
import
TemplateDict
raiser
=
self
.
_makeOne
(
type
=
'SyntaxError'
)
self
.
assertRaises
(
SyntaxError
,
raiser
.
render
,
TemplateDict
())
def
test_render_w_type_zExceptions_exception
(
self
):
from
DocumentTemplate.DT_Util
import
TemplateDict
from
zExceptions
import
Redirect
raiser
=
self
.
_makeOne
(
type
=
'Redirect'
)
self
.
assertRaises
(
Redirect
,
raiser
.
render
,
TemplateDict
())
def
test_render_w_type_nonesuch
(
self
):
from
DocumentTemplate.DT_Util
import
TemplateDict
raiser
=
self
.
_makeOne
(
type
=
'NonesuchError'
)
self
.
assertRaises
(
RuntimeError
,
raiser
.
render
,
TemplateDict
())
def
test_render_w_expr_builtin_exception
(
self
):
from
DocumentTemplate.DT_Util
import
TemplateDict
raiser
=
self
.
_makeOne
(
expr
=
'SyntaxError'
)
self
.
assertRaises
(
SyntaxError
,
raiser
.
render
,
TemplateDict
())
def
test_render_w_expr_zExceptions_exception
(
self
):
from
DocumentTemplate.DT_Util
import
TemplateDict
from
zExceptions
import
Redirect
raiser
=
self
.
_makeOne
(
expr
=
'Redirect'
)
self
.
assertRaises
(
Redirect
,
raiser
.
render
,
TemplateDict
())
def
test_render_w_expr_nonesuch
(
self
):
from
DocumentTemplate.DT_Raise
import
InvalidErrorTypeExpression
from
DocumentTemplate.DT_Util
import
TemplateDict
raiser
=
self
.
_makeOne
(
expr
=
'NonesuchError'
)
self
.
assertRaises
(
InvalidErrorTypeExpression
,
raiser
.
render
,
TemplateDict
())
class
DummySection
:
blocks
=
[
'dummy'
]
def
test_suite
():
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
Test_Raise
),
))
src/DocumentTemplate/tests/test_DT_Var.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2008 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Tests for functions and classes in DT_Var.
$Id$
"""
import
unittest
,
doctest
class
TestNewlineToBr
(
doctest
.
DocTestCase
):
def
test_newline_to_br
(
self
):
r"""
newline_to_br should work identically with either DOS-style or
Unix-style newlines.
>>> from DocumentTemplate import DT_Var
>>> text = '''
... line one
... line two
...
... line three
... '''
>>> print DT_Var.newline_to_br(text)
<br />
line one<br />
line two<br />
<br />
line three<br />
<BLANKLINE>
>>> dos = text.replace('\n', '\r\n')
>>> DT_Var.newline_to_br(text) == DT_Var.newline_to_br(dos)
True
"""
def
test_newline_to_br_tainted
(
self
):
"""
>>> from DocumentTemplate import DT_Var
>>> text = '''
... <li>line one</li>
... <li>line two</li>
... '''
>>> from AccessControl.tainted import TaintedString
>>> tainted = TaintedString(text)
>>> print DT_Var.newline_to_br(tainted)
<br />
<li>line one</li><br />
<li>line two</li><br />
<BLANKLINE>
"""
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
doctest
.
DocTestSuite
())
return
suite
if
__name__
==
'__main__'
:
unittest
.
main
(
defaultTest
=
'test_suite'
)
src/DocumentTemplate/tests/testustr.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ustr unit tests.
$Id$
"""
import
unittest
class
force_str
:
# A class whose string representation is not always a plain string:
def
__init__
(
self
,
s
):
self
.
s
=
s
def
__str__
(
self
):
return
self
.
s
class
Foo
(
str
):
pass
class
Bar
(
unicode
):
pass
class
UnicodeTests
(
unittest
.
TestCase
):
def
test_bare_string_literall
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
'hello'
)
self
.
assertEqual
(
a
,
'hello'
)
def
test_with_force_str
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
force_str
(
'hello'
))
self
.
assertEqual
(
a
,
'hello'
)
def
test_with_non_ascii_char
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
chr
(
200
))
self
.
assertEqual
(
a
,
chr
(
200
))
def
test_with_force_str_non_ascii_char
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
force_str
(
chr
(
200
)))
self
.
assertEqual
(
a
,
chr
(
200
))
def
test_with_int
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
22
)
self
.
assertEqual
(
a
,
'22'
)
def
test_with_list
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
([
1
,
2
,
3
])
self
.
assertEqual
(
a
,
'[1, 2, 3]'
)
def
test_w_unicode_literal
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
u'hello'
)
self
.
assertEqual
(
a
,
'hello'
)
def
test_w_force_str_unicode_literal
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
force_str
(
u'hello'
))
self
.
assertEqual
(
a
,
'hello'
)
def
test_w_unichr
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
unichr
(
200
))
self
.
assertEqual
(
a
,
unichr
(
200
))
def
test_w_force_str_unichr
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
force_str
(
unichr
(
200
)))
self
.
assertEqual
(
a
,
unichr
(
200
))
def
test_w_unichr_in_exception
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
ValueError
(
unichr
(
200
)))
self
.
assertEqual
(
a
,
unichr
(
200
))
def
testCustomStrings
(
self
):
from
DocumentTemplate.ustr
import
ustr
a
=
ustr
(
Foo
(
'foo'
))
self
.
assertEqual
(
type
(
a
),
Foo
)
a
=
ustr
(
Bar
(
'bar'
))
self
.
assertEqual
(
type
(
a
),
Bar
)
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
unittest
.
makeSuite
(
UnicodeTests
)
)
return
suite
src/DocumentTemplate/ustr.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ustr function.
$Id$
"""
nasty_exception_str
=
getattr
(
Exception
.
__str__
,
'im_func'
,
None
)
def
ustr
(
v
):
"""Convert any object to a plain string or unicode string,
minimising the chance of raising a UnicodeError. This
even works with uncooperative objects like Exceptions
"""
if
isinstance
(
v
,
basestring
):
return
v
else
:
fn
=
getattr
(
v
,
'__str__'
,
None
)
if
fn
is
not
None
:
# An object that wants to present its own string representation,
# but we dont know what type of string. We cant use any built-in
# function like str() or unicode() to retrieve it because
# they all constrain the type which potentially raises an exception.
# To avoid exceptions we have to call __str__ direct.
if
getattr
(
fn
,
'im_func'
,
None
)
==
nasty_exception_str
:
# Exception objects have been optimised into C, and their
# __str__ function fails when given a unicode object.
# Unfortunately this scenario is all too common when
# migrating to unicode, because of code which does:
# raise ValueError(something_I_wasnt_expecting_to_be_unicode)
return
_exception_str
(
v
)
else
:
# Trust the object to do this right
v
=
fn
()
if
isinstance
(
v
,
basestring
):
return
v
else
:
raise
ValueError
(
'__str__ returned wrong type'
)
# Drop through for non-instance types, and instances that
# do not define a special __str__
return
str
(
v
)
def
_exception_str
(
exc
):
if
hasattr
(
exc
,
'args'
):
if
not
exc
.
args
:
return
''
elif
len
(
exc
.
args
)
==
1
:
return
ustr
(
exc
.
args
[
0
])
else
:
return
str
(
exc
.
args
)
return
str
(
exc
)
src/OFS/misc_.py
View file @
ca3753b2
...
...
@@ -36,8 +36,8 @@ class p_:
davlocked
=
ImageFile
(
'webdav/www/davlock.gif'
)
pl
=
ImageFile
(
'
TreeDisplay
/www/Plus_icon.gif'
)
mi
=
ImageFile
(
'
TreeDisplay
/www/Minus_icon.gif'
)
pl
=
ImageFile
(
'
OFS
/www/Plus_icon.gif'
)
mi
=
ImageFile
(
'
OFS
/www/Minus_icon.gif'
)
rtab
=
ImageFile
(
'App/www/rtab.gif'
)
ltab
=
ImageFile
(
'App/www/ltab.gif'
)
sp
=
ImageFile
(
'App/www/sp.gif'
)
...
...
src/
TreeDisplay
/www/Minus_icon.gif
→
src/
OFS
/www/Minus_icon.gif
View file @
ca3753b2
File moved
src/
TreeDisplay
/www/Plus_icon.gif
→
src/
OFS
/www/Plus_icon.gif
View file @
ca3753b2
File moved
src/TreeDisplay/TreeTag.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Rendering object hierarchies as Trees
"""
__rcs_id__
=
'$Id$'
__version__
=
'$Revision: 1.58 $'
[
11
:
-
2
]
from
binascii
import
a2b_base64
from
binascii
import
b2a_base64
from
cPickle
import
dumps
import
re
from
string
import
translate
from
urllib
import
quote
from
urllib
import
unquote
from
zlib
import
compress
from
zlib
import
decompressobj
#from DocumentTemplate.DT_Util import *
from
DocumentTemplate.DT_Util
import
add_with_prefix
from
DocumentTemplate.DT_Util
import
Eval
from
DocumentTemplate.DT_Util
import
InstanceDict
from
DocumentTemplate.DT_Util
import
name_param
from
DocumentTemplate.DT_Util
import
parse_params
from
DocumentTemplate.DT_Util
import
ParseError
from
DocumentTemplate.DT_Util
import
render_blocks
from
DocumentTemplate.DT_Util
import
simple_name
from
DocumentTemplate.DT_String
import
String
tbl
=
''
.
join
(
map
(
chr
,
range
(
256
)))
tplus
=
tbl
[:
ord
(
'+'
)]
+
'-'
+
tbl
[
ord
(
'+'
)
+
1
:]
tminus
=
tbl
[:
ord
(
'-'
)]
+
'+'
+
tbl
[
ord
(
'-'
)
+
1
:]
class
Tree
:
name
=
'tree'
blockContinuations
=
()
expand
=
None
def
__init__
(
self
,
blocks
):
tname
,
args
,
section
=
blocks
[
0
]
args
=
parse_params
(
args
,
name
=
None
,
expr
=
None
,
nowrap
=
1
,
expand
=
None
,
leaves
=
None
,
header
=
None
,
footer
=
None
,
branches
=
None
,
branches_expr
=
None
,
sort
=
None
,
reverse
=
1
,
skip_unauthorized
=
1
,
id
=
None
,
single
=
1
,
url
=
None
,
# opened_decoration=None,
# closed_decoration=None,
# childless_decoration=None,
assume_children
=
1
,
urlparam
=
None
,
prefix
=
None
)
has_key
=
args
.
has_key
if
has_key
(
''
)
or
has_key
(
'name'
)
or
has_key
(
'expr'
):
name
,
expr
=
name_param
(
args
,
'tree'
,
1
)
if
expr
is
not
None
:
args
[
'expr'
]
=
expr
elif
has_key
(
''
):
args
[
'name'
]
=
name
else
:
name
=
'a tree tag'
if
has_key
(
'branches_expr'
):
if
has_key
(
'branches'
):
raise
ParseError
,
_tm
(
'branches and and branches_expr given'
,
'tree'
)
args
[
'branches_expr'
]
=
Eval
(
args
[
'branches_expr'
]).
eval
elif
not
has_key
(
'branches'
):
args
[
'branches'
]
=
'tpValues'
if
not
has_key
(
'id'
):
args
[
'id'
]
=
'tpId'
if
not
has_key
(
'url'
):
args
[
'url'
]
=
'tpURL'
if
not
has_key
(
'childless_decoration'
):
args
[
'childless_decoration'
]
=
''
prefix
=
args
.
get
(
'prefix'
)
if
prefix
and
not
simple_name
(
prefix
):
raise
ParseError
,
_tm
(
'prefix is not a simple name'
,
'tree'
)
self
.
__name__
=
name
self
.
section
=
section
.
blocks
self
.
args
=
args
def
render
(
self
,
md
):
args
=
self
.
args
have
=
args
.
has_key
if
have
(
'name'
):
v
=
md
[
args
[
'name'
]]
elif
have
(
'expr'
):
v
=
args
[
'expr'
].
eval
(
md
)
else
:
v
=
md
.
this
return
tpRender
(
v
,
md
,
self
.
section
,
self
.
args
)
__call__
=
render
String
.
commands
[
'tree'
]
=
Tree
pyid
=
id
# Copy builtin
simple_types
=
{
str
:
1
,
unicode
:
1
,
int
:
1
,
float
:
1
,
long
:
1
,
tuple
:
1
,
list
:
1
,
dict
:
1
}
def
try_call_attr
(
ob
,
attrname
,
simple_types
=
simple_types
):
attr
=
getattr
(
ob
,
attrname
)
if
type
(
attr
)
in
simple_types
:
return
attr
try
:
return
attr
()
except
TypeError
:
return
attr
def
tpRender
(
self
,
md
,
section
,
args
,
try_call_attr
=
try_call_attr
):
"""Render data organized as a tree.
We keep track of open nodes using a cookie. The cookie stored the
tree state. State should be a tree represented like:
[] # all closed
['eagle'], # eagle is open
['eagle'], ['jeep', [1983, 1985]] # eagle, jeep, 1983 jeep and 1985 jeep
where the items are object ids. The state will be pickled to a
compressed and base64ed string that gets unencoded, uncompressed,
and unpickled on the other side.
Note that ids used in state need not be connected to urls, since
state manipulation is internal to rendering logic.
Note that to make unpickling safe, we use the MiniPickle module,
that only creates safe objects
"""
data
=
[]
idattr
=
args
[
'id'
]
if
hasattr
(
self
,
idattr
):
id
=
try_call_attr
(
self
,
idattr
)
elif
hasattr
(
self
,
'_p_oid'
):
id
=
oid
(
self
)
else
:
id
=
pyid
(
self
)
try
:
# see if we are being run as a sub-document
root
=
md
[
'tree-root-url'
]
url
=
md
[
'tree-item-url'
]
state
=
md
[
'tree-state'
]
diff
=
md
[
'tree-diff'
]
substate
=
md
[
'-tree-substate-'
]
colspan
=
md
[
'tree-colspan'
]
level
=
md
[
'tree-level'
]
except
KeyError
:
# OK, we are a top-level invocation
level
=-
1
if
md
.
has_key
(
'collapse_all'
):
state
=
[
id
,[]],
elif
md
.
has_key
(
'expand_all'
):
have_arg
=
args
.
has_key
if
have_arg
(
'branches'
):
def
get_items
(
node
,
branches
=
args
[
'branches'
],
md
=
md
):
get
=
md
.
guarded_getattr
if
get
is
None
:
get
=
getattr
items
=
get
(
node
,
branches
)
return
items
()
elif
have_arg
(
'branches_expr'
):
def
get_items
(
node
,
branches_expr
=
args
[
'branches_expr'
],
md
=
md
):
md
.
_push
(
InstanceDict
(
node
,
md
))
items
=
branches_expr
(
md
)
md
.
_pop
()
return
items
state
=
[
id
,
tpValuesIds
(
self
,
get_items
,
args
)],
else
:
if
md
.
has_key
(
'tree-s'
):
state
=
md
[
'tree-s'
]
state
=
decode_seq
(
state
)
try
:
if
state
[
0
][
0
]
!=
id
:
state
=
[
id
,[]],
except
IndexError
:
state
=
[
id
,[]],
else
:
state
=
[
id
,[]],
if
md
.
has_key
(
'tree-e'
):
diff
=
decode_seq
(
md
[
'tree-e'
])
apply_diff
(
state
,
diff
,
1
)
if
md
.
has_key
(
'tree-c'
):
diff
=
decode_seq
(
md
[
'tree-c'
])
apply_diff
(
state
,
diff
,
0
)
colspan
=
tpStateLevel
(
state
)
substate
=
state
diff
=
[]
url
=
''
root
=
md
[
'URL'
]
l
=
root
.
rfind
(
'/'
)
if
l
>=
0
:
root
=
root
[
l
+
1
:]
treeData
=
{
'tree-root-url'
:
root
,
'tree-colspan'
:
colspan
,
'tree-state'
:
state
}
prefix
=
args
.
get
(
'prefix'
)
if
prefix
:
for
k
,
v
in
treeData
.
items
():
treeData
[
prefix
+
k
[
4
:].
replace
(
'-'
,
'_'
)]
=
v
md
.
_push
(
InstanceDict
(
self
,
md
))
md
.
_push
(
treeData
)
try
:
tpRenderTABLE
(
self
,
id
,
root
,
url
,
state
,
substate
,
diff
,
data
,
colspan
,
section
,
md
,
treeData
,
level
,
args
)
finally
:
md
.
_pop
(
2
)
if
state
is
substate
and
not
(
args
.
has_key
(
'single'
)
and
args
[
'single'
]):
state
=
state
or
([
id
],)
state
=
encode_seq
(
state
)
md
[
'RESPONSE'
].
setCookie
(
'tree-s'
,
state
)
return
''
.
join
(
data
)
def
tpRenderTABLE
(
self
,
id
,
root_url
,
url
,
state
,
substate
,
diff
,
data
,
colspan
,
section
,
md
,
treeData
,
level
=
0
,
args
=
None
,
try_call_attr
=
try_call_attr
,
):
"Render a tree as a table"
have_arg
=
args
.
has_key
exp
=
0
if
level
>=
0
:
urlattr
=
args
[
'url'
]
if
urlattr
and
hasattr
(
self
,
urlattr
):
tpUrl
=
try_call_attr
(
self
,
urlattr
)
url
=
(
url
and
(
'%s/%s'
%
(
url
,
tpUrl
)))
or
tpUrl
root_url
=
root_url
or
tpUrl
ptreeData
=
add_with_prefix
(
treeData
,
'tree'
,
args
.
get
(
'prefix'
))
ptreeData
[
'tree-item-url'
]
=
url
ptreeData
[
'tree-level'
]
=
level
ptreeData
[
'tree-item-expanded'
]
=
0
idattr
=
args
[
'id'
]
output
=
data
.
append
items
=
None
if
(
have_arg
(
'assume_children'
)
and
args
[
'assume_children'
]
and
substate
is
not
state
):
# We should not compute children unless we have to.
# See if we've been asked to expand our children.
for
i
in
range
(
len
(
substate
)):
sub
=
substate
[
i
]
if
sub
[
0
]
==
id
:
exp
=
i
+
1
break
if
not
exp
:
items
=
1
get
=
md
.
guarded_getattr
if
get
is
None
:
get
=
getattr
if
items
is
None
:
if
have_arg
(
'branches'
)
and
hasattr
(
self
,
args
[
'branches'
]):
items
=
get
(
self
,
args
[
'branches'
])
items
=
items
()
elif
have_arg
(
'branches_expr'
):
items
=
args
[
'branches_expr'
](
md
)
if
not
items
and
have_arg
(
'leaves'
):
items
=
1
if
items
and
items
!=
1
:
getitem
=
getattr
(
md
,
'guarded_getitem'
,
None
)
if
getitem
is
not
None
:
unauth
=
[]
for
index
in
range
(
len
(
items
)):
try
:
getitem
(
items
,
index
)
except
ValidationError
:
unauth
.
append
(
index
)
if
unauth
:
if
have_arg
(
'skip_unauthorized'
)
and
args
[
'skip_unauthorized'
]:
items
=
list
(
items
)
unauth
.
reverse
()
for
index
in
unauth
:
del
items
[
index
]
else
:
raise
ValidationError
,
unauth
if
have_arg
(
'sort'
):
# Faster/less mem in-place sort
if
type
(
items
)
==
type
(()):
items
=
list
(
items
)
sort
=
args
[
'sort'
]
size
=
range
(
len
(
items
))
for
i
in
size
:
v
=
items
[
i
]
k
=
getattr
(
v
,
sort
)
try
:
k
=
k
()
except
:
pass
items
[
i
]
=
(
k
,
v
)
items
.
sort
()
for
i
in
size
:
items
[
i
]
=
items
[
i
][
1
]
if
have_arg
(
'reverse'
):
items
=
list
(
items
)
# Copy the list
items
.
reverse
()
diff
.
append
(
id
)
_td_colspan
=
'<td colspan="%s" style="white-space: nowrap"></td>'
_td_single
=
'<td width="16" style="white-space: nowrap"></td>'
sub
=
None
if
substate
is
state
:
output
(
'<table cellspacing="0">
\
n
'
)
sub
=
substate
[
0
]
exp
=
items
else
:
# Add prefix
output
(
'<tr>
\
n
'
)
# Add +/- icon
if
items
:
if
level
:
if
level
>
3
:
output
(
_td_colspan
%
(
level
-
1
))
elif
level
>
1
:
output
(
_td_single
*
(
level
-
1
))
output
(
_td_single
)
output
(
'
\
n
'
)
output
(
'<td width="16" valign="top" style="white-space: nowrap">'
)
for
i
in
range
(
len
(
substate
)):
sub
=
substate
[
i
]
if
sub
[
0
]
==
id
:
exp
=
i
+
1
break
####################################
# Mostly inline encode_seq for speed
s
=
compress
(
dumps
(
diff
,
1
))
if
len
(
s
)
>
57
:
s
=
encode_str
(
s
)
else
:
s
=
b2a_base64
(
s
)[:
-
1
]
l
=
s
.
find
(
'='
)
if
l
>=
0
:
s
=
s
[:
l
]
s
=
translate
(
s
,
tplus
)
####################################
script
=
md
[
'BASEPATH1'
]
# Propagate extra args through tree.
if
args
.
has_key
(
'urlparam'
):
param
=
args
[
'urlparam'
]
param
=
"%s&"
%
param
else
:
param
=
""
if
exp
:
ptreeData
[
'tree-item-expanded'
]
=
1
output
(
'<a name="%s" href="%s?%stree-c=%s#%s">'
'<img src="%s/p_/mi" alt="-" border="0" /></a>'
%
(
id
,
root_url
,
param
,
s
,
id
,
script
))
else
:
output
(
'<a name="%s" href="%s?%stree-e=%s#%s">'
'<img src="%s/p_/pl" alt="+" border="0" /></a>'
%
(
id
,
root_url
,
param
,
s
,
id
,
script
))
output
(
'</td>
\
n
'
)
else
:
if
level
>
2
:
output
(
_td_colspan
%
level
)
elif
level
>
0
:
output
(
_td_single
*
level
)
output
(
_td_single
)
output
(
'
\
n
'
)
# add item text
dataspan
=
colspan
-
level
output
(
'<td%s%s valign="top" align="left">'
%
((
dataspan
>
1
and
(
' colspan="%s"'
%
dataspan
)
or
''
),
(
have_arg
(
'nowrap'
)
and
args
[
'nowrap'
]
and
' style="white-space: nowrap"'
or
''
))
)
output
(
render_blocks
(
section
,
md
))
output
(
'</td>
\
n
</tr>
\
n
'
)
if
exp
:
level
=
level
+
1
dataspan
=
colspan
-
level
if
level
>
2
:
h
=
_td_colspan
%
level
elif
level
>
0
:
h
=
_td_single
*
level
else
:
h
=
''
if
have_arg
(
'header'
):
doc
=
args
[
'header'
]
if
md
.
has_key
(
doc
):
doc
=
md
.
getitem
(
doc
,
0
)
else
:
doc
=
None
if
doc
is
not
None
:
output
(
doc
(
None
,
md
,
standard_html_header
=
(
'<tr>%s'
'<td width="16" style="white-space: nowrap"></td>'
'<td%s valign="top">'
%
(
h
,
(
dataspan
>
1
and
(
' colspan="%s"'
%
dataspan
)
or
''
))),
standard_html_footer
=
'</td></tr>'
,
))
if
items
==
1
:
# leaves
if
have_arg
(
'leaves'
):
doc
=
args
[
'leaves'
]
if
md
.
has_key
(
doc
):
doc
=
md
.
getitem
(
doc
,
0
)
else
:
doc
=
None
if
doc
is
not
None
:
treeData
[
'-tree-substate-'
]
=
sub
ptreeData
[
'tree-level'
]
=
level
md
.
_push
(
treeData
)
try
:
output
(
doc
(
None
,
md
,
standard_html_header
=
(
'<tr>%s'
'<td width="16" style="white-space: nowrap"></td>'
'<td%s valign="top">'
%
(
h
,
(
dataspan
>
1
and
(
' colspan="%s"'
%
dataspan
)
or
''
))),
standard_html_footer
=
'</td></tr>'
,
))
finally
:
md
.
_pop
(
1
)
elif
have_arg
(
'expand'
):
doc
=
args
[
'expand'
]
if
md
.
has_key
(
doc
):
doc
=
md
.
getitem
(
doc
,
0
)
else
:
doc
=
None
if
doc
is
not
None
:
treeData
[
'-tree-substate-'
]
=
sub
ptreeData
[
'tree-level'
]
=
level
md
.
_push
(
treeData
)
try
:
output
(
doc
(
None
,
md
,
standard_html_header
=
(
'<tr>%s<td width="16" style="white-space: nowrap"></td>'
'<td%s valign="top">'
%
(
h
,
(
dataspan
>
1
and
(
' colspan="%s"'
%
dataspan
)
or
''
))),
standard_html_footer
=
'</td></tr>'
,
))
finally
:
md
.
_pop
(
1
)
else
:
__traceback_info__
=
sub
,
args
,
state
,
substate
ids
=
{}
for
item
in
items
:
if
hasattr
(
item
,
idattr
):
id
=
try_call_attr
(
item
,
idattr
)
elif
hasattr
(
item
,
'_p_oid'
):
id
=
oid
(
item
)
else
:
id
=
pyid
(
item
)
if
len
(
sub
)
==
1
:
sub
.
append
([])
substate
=
sub
[
1
]
ids
[
id
]
=
1
md
.
_push
(
InstanceDict
(
item
,
md
))
try
:
data
=
tpRenderTABLE
(
item
,
id
,
root_url
,
url
,
state
,
substate
,
diff
,
data
,
colspan
,
section
,
md
,
treeData
,
level
,
args
)
finally
:
md
.
_pop
()
if
not
sub
[
1
]:
del
sub
[
1
]
ids
=
ids
.
has_key
for
i
in
range
(
len
(
substate
)
-
1
,
-
1
):
if
not
ids
(
substate
[
i
][
0
]):
del
substate
[
i
]
if
have_arg
(
'footer'
):
doc
=
args
[
'footer'
]
if
md
.
has_key
(
doc
):
doc
=
md
.
getitem
(
doc
,
0
)
else
:
doc
=
None
if
doc
is
not
None
:
output
(
doc
(
None
,
md
,
standard_html_header
=
(
'<tr>%s<td width="16" style="white-space: nowrap"></td>'
'<td%s valign="top">'
%
(
h
,
(
dataspan
>
1
and
(
' colspan="%s"'
%
dataspan
)
or
''
))),
standard_html_footer
=
'</td></tr>'
,
))
del
diff
[
-
1
]
if
not
diff
:
output
(
'</table>
\
n
'
)
return
data
def
apply_diff
(
state
,
diff
,
expand
):
if
not
diff
:
return
s
=
[
None
,
state
]
diff
.
reverse
()
__traceback_info__
=
s
,
diff
while
diff
:
id
=
diff
[
-
1
]
del
diff
[
-
1
]
if
len
(
s
)
==
1
:
s
.
append
([])
s
=
s
[
1
]
if
type
(
s
)
==
type
(()):
s
=
list
(
s
)
loc
=-
1
for
i
in
range
(
len
(
s
)):
if
s
[
i
][
0
]
==
id
:
loc
=
i
break
if
loc
>=
0
:
if
not
diff
and
not
expand
:
del
s
[
loc
]
else
:
s
=
s
[
loc
]
elif
diff
or
expand
:
s
.
append
([
id
,[]])
s
=
s
[
-
1
][
1
]
while
diff
:
id
=
diff
[
-
1
]
del
diff
[
-
1
]
if
diff
or
expand
:
s
.
append
([
id
,[]])
s
=
s
[
-
1
][
1
]
def
encode_seq
(
state
):
"Convert a sequence to an encoded string"
state
=
compress
(
dumps
(
state
))
l
=
len
(
state
)
if
l
>
57
:
states
=
[]
for
i
in
range
(
0
,
l
,
57
):
states
.
append
(
b2a_base64
(
state
[
i
:
i
+
57
])[:
-
1
])
state
=
''
.
join
(
states
)
else
:
state
=
b2a_base64
(
state
)[:
-
1
]
l
=
state
.
find
(
'='
)
if
l
>=
0
:
state
=
state
[:
l
]
state
=
translate
(
state
,
tplus
)
return
state
def
encode_str
(
state
):
"Convert a sequence to an encoded string"
l
=
len
(
state
)
if
l
>
57
:
states
=
[]
for
i
in
range
(
0
,
l
,
57
):
states
.
append
(
b2a_base64
(
state
[
i
:
i
+
57
])[:
-
1
])
state
=
''
.
join
(
states
)
else
:
state
=
b2a_base64
(
state
)[:
-
1
]
l
=
state
.
find
(
'='
)
if
l
>=
0
:
state
=
state
[:
l
]
state
=
translate
(
state
,
tplus
)
return
state
def
decode_seq
(
state
):
"Convert an encoded string to a sequence"
state
=
translate
(
state
,
tminus
)
l
=
len
(
state
)
if
l
>
76
:
states
=
[]
j
=
0
for
i
in
range
(
l
/
76
):
k
=
j
+
76
states
.
append
(
a2b_base64
(
state
[
j
:
k
]))
j
=
k
if
j
<
l
:
state
=
state
[
j
:]
l
=
len
(
state
)
k
=
l
%
4
if
k
:
state
=
state
+
'='
*
(
4
-
k
)
states
.
append
(
a2b_base64
(
state
))
state
=
''
.
join
(
states
)
else
:
l
=
len
(
state
)
k
=
l
%
4
if
k
:
state
=
state
+
'='
*
(
4
-
k
)
state
=
a2b_base64
(
state
)
state
=
decompress
(
state
)
try
:
return
list
(
MiniUnpickler
(
StringIO
(
state
)).
load
())
except
:
return
[]
def
decompress
(
input
,
max_size
=
10240
):
# This sillyness can go away in python 2.2
d
=
decompressobj
()
output
=
''
while
input
:
fragment_size
=
max
(
1
,(
max_size
-
len
(
output
))
/
1000
)
fragment
,
input
=
input
[:
fragment_size
],
input
[
fragment_size
:]
output
+=
d
.
decompress
(
fragment
)
if
len
(
output
)
>
max_size
:
raise
ValueError
(
'Compressed input too large'
)
return
output
+
d
.
flush
()
def
tpStateLevel
(
state
,
level
=
0
):
for
sub
in
state
:
if
len
(
sub
)
==
2
:
level
=
max
(
level
,
1
+
tpStateLevel
(
sub
[
1
]))
else
:
level
=
max
(
level
,
1
)
return
level
def
tpValuesIds
(
self
,
get_items
,
args
,
try_call_attr
=
try_call_attr
,
):
# get_item(node) is a function that returns the subitems of node
# This should build the ids of subitems which are
# expandable (non-empty). Leaves should never be
# in the state - it will screw the colspan counting.
r
=
[]
idattr
=
args
[
'id'
]
try
:
try
:
items
=
get_items
(
self
)
except
AttributeError
:
items
=
()
for
item
in
items
:
try
:
if
get_items
(
item
):
if
hasattr
(
item
,
idattr
):
id
=
try_call_attr
(
item
,
idattr
)
elif
hasattr
(
item
,
'_p_oid'
):
id
=
oid
(
item
)
else
:
id
=
pyid
(
item
)
e
=
tpValuesIds
(
item
,
get_items
,
args
)
if
e
:
id
=
[
id
,
e
]
else
:
id
=
[
id
]
r
.
append
(
id
)
except
:
pass
except
:
pass
return
r
def
oid
(
self
):
return
b2a_base64
(
str
(
self
.
_p_oid
))[:
-
1
]
#icoSpace='<IMG SRC="Blank_icon" BORDER="0">'
#icoPlus ='<IMG SRC="Plus_icon" BORDER="0">'
#icoMinus='<IMG SRC="Minus_icon" BORDER="0">'
###############################################################################
## Everthing below here should go in a MiniPickle.py module, but keeping it
## internal makes an easier patch
import
pickle
from
cStringIO
import
StringIO
if
pickle
.
format_version
!=
"2.0"
:
# Maybe the format changed, and opened a security hole
raise
'Invalid pickle version'
class
MiniUnpickler
(
pickle
.
Unpickler
):
"""An unpickler that can only handle simple types.
"""
def
refuse_to_unpickle
(
self
):
raise
pickle
.
UnpicklingError
,
'Refused'
dispatch
=
pickle
.
Unpickler
.
dispatch
.
copy
()
for
k
,
v
in
dispatch
.
items
():
if
k
==
''
or
k
in
'().012FGIJKLMNTUVXS]adeghjlpqrstu}'
:
# This key is necessary and safe, so leave it in the map
pass
else
:
dispatch
[
k
]
=
refuse_to_unpickle
# Anything unnecessary is banned, but here is some logic to explain why
if
k
in
[
pickle
.
GLOBAL
,
pickle
.
OBJ
,
pickle
.
INST
,
pickle
.
REDUCE
,
pickle
.
BUILD
]:
# These are definite security holes
pass
elif
k
in
[
pickle
.
PERSID
,
pickle
.
BINPERSID
]:
# These are just unnecessary
pass
del
k
del
v
def
_should_succeed
(
x
,
binary
=
1
):
if
x
!=
MiniUnpickler
(
StringIO
(
pickle
.
dumps
(
x
,
binary
))).
load
():
raise
ValueError
(
x
)
def
_should_fail
(
x
,
binary
=
1
):
try
:
MiniUnpickler
(
StringIO
(
pickle
.
dumps
(
x
,
binary
))).
load
()
raise
ValueError
(
x
)
except
pickle
.
UnpicklingError
,
e
:
if
e
[
0
]
!=
'Refused'
:
raise
ValueError
(
x
)
class
_junk_class
:
pass
def
_test
():
_should_succeed
(
'hello'
)
_should_succeed
(
1
)
_should_succeed
(
1L
)
_should_succeed
(
1.0
)
_should_succeed
((
1
,
2
,
3
))
_should_succeed
([
1
,
2
,
3
])
_should_succeed
({
1
:
2
,
3
:
4
})
_should_fail
(
open
)
_should_fail
(
_junk_class
)
_should_fail
(
_junk_class
())
# Test MiniPickle on every import
_test
()
src/TreeDisplay/__init__.py
deleted
100644 → 0
View file @
13bc9b23
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import
TreeTag
src/TreeDisplay/www/Blank_icon.gif
deleted
100644 → 0
View file @
13bc9b23
832 Bytes
versions.cfg
View file @
ca3753b2
...
...
@@ -7,6 +7,7 @@ Zope2 =
AccessControl = 2.13.1
Acquisition = 2.13.3
DateTime = 2.12.2
DocumentTemplate = 2.13.0
ExtensionClass = 2.13.2
initgroups = 2.13.0
Missing = 2.13.1
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment