[Zope-Checkins]
SVN: Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py
This version is now fully functional and without dependencies
from Products.PageTemplates
Andreas Jung
andreas at andreas-jung.com
Sun Dec 11 07:02:36 EST 2005
Log message for revision 40698:
This version is now fully functional and without dependencies from Products.PageTemplates
Changed:
U Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py
D Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py.scary
-=-
Modified: Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py 2005-12-11 11:21:09 UTC (rev 40697)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py 2005-12-11 12:02:36 UTC (rev 40698)
@@ -16,36 +16,41 @@
__version__='$Revision: 1.48 $'[11:-2]
import re
-from urllib import quote
-import os, AccessControl, Acquisition
+import os
+import Acquisition
from Globals import ImageFile, package_home, InitializeClass
from OFS.SimpleItem import SimpleItem
from OFS.content_types import guess_content_type
from DateTime.DateTime import DateTime
from Shared.DC.Scripts.Script import Script
from Shared.DC.Scripts.Signature import FuncCode
-from AccessControl import getSecurityManager
from OFS.History import Historical, html_diff
from OFS.Cache import Cacheable
from OFS.Traversable import Traversable
from OFS.PropertyManager import PropertyManager
-from Products.PageTemplates.Expressions import SecureModuleImporter
-from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-
-from AccessControl import Unauthorized
+from AccessControl import getSecurityManager, safe_builtins, ClassSecurityInfo
from AccessControl.Permissions import view, ftp_access, change_page_templates, view_management_screens
from webdav.Lockable import ResourceLockedError
from webdav.WriteLockInterface import WriteLockInterface
-
from zope.pagetemplate.pagetemplate import PageTemplate
-#from zope.pagetemplate.pagetemplatefile import PageTemplateFile
# regular expression to extract the encoding from the XML preamble
encoding_reg= re.compile('<\?xml.*?encoding="(.*?)".*?\?>', re.M)
+
+class SecureModuleImporter:
+ __allow_access_to_unprotected_subobjects__ = 1
+ def __getitem__(self, module):
+ mod = safe_builtins['__import__'](module)
+ path = module.split('.')
+ for name in path[1:]:
+ mod = getattr(mod, name)
+ return mod
+
+
class Src(Acquisition.Explicit):
""" I am scary code """
@@ -64,6 +69,7 @@
def sniffEncoding(text, default_encoding='utf-8'):
""" try to determine the encoding from html or xml """
+ # XXX: look at pagetemplates.py (BOM!!!)
if text.startswith('<?xml'):
mo = encoding_reg.search(text)
if mo:
@@ -101,12 +107,13 @@
{'id':'expand', 'type':'boolean', 'mode': 'w'},
)
- security = AccessControl.ClassSecurityInfo()
+ security = ClassSecurityInfo()
security.declareObjectProtected(view)
security.declareProtected(view, '__call__')
def __init__(self, id, text=None, content_type=None, encoding='utf-8'):
self.id = id
+ self.expand = 0
self.ZBindings_edit(self._default_bindings)
self.pt_edit(text, content_type, encoding)
@@ -124,15 +131,8 @@
def pt_edit(self, text, content_type, encoding='utf-8'):
text = text.strip()
-# if content_type == 'text/html':
-# if not text.startswith('<?xml'):
-# # not XHTML -> convert it to unicode
-# text = unicode(text, encoding)
-
if not isinstance(text, unicode):
text = unicode(text, encoding)
-
- print content_type, type(text),repr(text)
self.ZCacheable_invalidate()
PageTemplate.pt_edit(self, text, content_type)
@@ -238,7 +238,7 @@
'options': {},
'root': root,
'request': getattr(root, 'REQUEST', None),
- 'modules': SecureModuleImporter,
+ 'modules': SecureModuleImporter(),
}
return c
@@ -258,7 +258,7 @@
except AttributeError:
pass
- security=getSecurityManager()
+ security = AccessControl.getSecurityManager()
bound_names['user'] = security.getUser()
# Retrieve the value from the cache.
@@ -332,6 +332,9 @@
def document_src(self, REQUEST=None, RESPONSE=None):
"""Return expanded document source."""
+ print 'src', self.read()
+
+
if RESPONSE is not None:
RESPONSE.setHeader('Content-Type', 'text/plain')
if REQUEST is not None and REQUEST.get('raw'):
@@ -363,15 +366,10 @@
def wl_isLocked(self):
return 0
- security.declareProtected(view_management_screens, 'source_dot_xml')
+ security.declareProtected(view_management_screens, 'getSource')
+ getSource = Src()
source_dot_xml = Src()
- security.declareProtected(view_management_screens, 'pt_editForm')
- pt_editForm = PageTemplateFile('pt/ptEdit.pt', globals())
- pt_editForm.__name__ = 'pt_editForm'
- manage = manage_main = pt_editForm
-
-
InitializeClass(ZPT)
@@ -379,22 +377,31 @@
setattr(ZPT, 'source.html', ZPT.source_dot_xml)
+def _newZPT(id, filename):
+ """ factory to generate ZPT instances from the file-system
+ based templates (basically for internal purposes)
+ """
+ zpt = ZPT(id, open(filename).read(), 'text/html')
+ zpt.__name__= id
+ return zpt
class FSZPT(ZPT):
+ """ factory to generate ZPT instances from the file-system
+ based templates (basically for internal purposes)
+ """
- def __init__(self, filename, name):
- self.__name__= name
- PageTemplate.__init__(self, open(filename).read(), 'text/html')
+ def __init__(self, id, filename):
+ ZPT.__init__(self, id, open(filename).read(), 'text/html')
+ self.__name__= id
InitializeClass(FSZPT)
-# Product registration and Add support
-manage_addZPTForm= PageTemplateFile('pt/ptAdd.pt', globals())
-manage_addZPTForm.__name__ = 'manage_addZPTForm'
-#manage_addZPTForm= FSZPT(os.path.join(package_home(globals()), 'pt', 'ptAdd.pt'), 'manage_addZPTForm')
-#manage_addZPTForm.__name__ = 'manage_addZPTForm'
+ZPT.pt_editForm = FSZPT('pt_editForm', os.path.join(package_home(globals()),'pt', 'ptEdit.pt'))
+# this is scary, do we need this?
+ZPT.manage = ZPT.manage_main = ZPT.pt_editForm
+manage_addZPTForm= FSZPT('manage_addZPTForm', os.path.join(package_home(globals()), 'pt', 'ptAdd.pt'))
def manage_addZPT(self, id, title='', file=None, encoding='utf-8', submit=None, RESPONSE=None):
"Add a Page Template with optional file content."
@@ -422,7 +429,7 @@
else:
return zpt
-from Products.PageTemplates import misc_
+from Products.ZPT import misc_
misc_['exclamation.gif'] = ImageFile('pt/exclamation.gif', globals())
def initialize(context):
Deleted: Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py.scary
===================================================================
--- Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py.scary 2005-12-11 11:21:09 UTC (rev 40697)
+++ Zope/branches/ajung-zpt-integration/lib/python/Products/ZPT/ZPT.py.scary 2005-12-11 12:02:36 UTC (rev 40698)
@@ -1,446 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
-#
-# 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
-#
-##############################################################################
-
-""" Zope Page Template module (wrapper for the Zope 3 ZPT implementation) """
-
-__version__='$Revision: 1.48 $'[11:-2]
-
-import re
-from urllib import quote
-import os, AccessControl, Acquisition
-from Globals import ImageFile, package_home, InitializeClass
-from OFS.SimpleItem import SimpleItem
-from OFS.content_types import guess_content_type
-from DateTime.DateTime import DateTime
-from Shared.DC.Scripts.Script import Script
-from Shared.DC.Scripts.Signature import FuncCode
-from AccessControl import getSecurityManager
-
-from OFS.History import Historical, html_diff
-from OFS.Cache import Cacheable
-from OFS.Traversable import Traversable
-from OFS.PropertyManager import PropertyManager
-
-from Products.PageTemplates.Expressions import SecureModuleImporter
-
-from AccessControl import Unauthorized
-from AccessControl.Permissions import view, ftp_access, change_page_templates, view_management_screens
-
-from webdav.Lockable import ResourceLockedError
-from webdav.WriteLockInterface import WriteLockInterface
-from zope.pagetemplate.pagetemplate import PageTemplate
-
-# regular expression to extract the encoding from the XML preamble
-encoding_reg= re.compile('<\?xml.*?encoding="(.*?)".*?\?>', re.M)
-
-class Src(Acquisition.Explicit):
- """ I am scary code """
-
- index_html = None
- PUT = document_src = Acquisition.Acquired
-
- def __before_publishing_traverse__(self, ob, request):
- if getattr(request, '_hacked_path', 0):
- request._hacked_path = 0
-
- def __call__(self, REQUEST, RESPONSE):
- " "
- return self.document_src(REQUEST)
-
-
-def sniffEncoding(text, default_encoding='utf-8'):
- """ try to determine the encoding from html or xml """
-
- # XXX: look at pagetemplates.py (BOM!!!)
- if text.startswith('<?xml'):
- mo = encoding_reg.search(text)
- if mo:
- return mo.group(1)
- return default_encoding
-
-_default_content_fn = os.path.join(package_home(globals()), 'pt', 'default.html')
-
-
-class ZPT(Script, PageTemplate, Historical, Cacheable,
- Traversable, PropertyManager):
- """ Z2 wrapper class for Zope 3 page templates """
-
- __implements__ = (WriteLockInterface,)
-
- meta_type = 'ZPT'
-
- func_defaults = None
- func_code = FuncCode((), 0)
-
- _default_bindings = {'name_subpath': 'traverse_subpath'}
-
- manage_options = (
- {'label':'Edit', 'action':'pt_editForm',
- 'help': ('PageTemplates', 'PageTemplate_Edit.stx')},
- {'label':'Test', 'action':'ZScriptHTML_tryForm'},
- ) + PropertyManager.manage_options \
- + Historical.manage_options \
- + SimpleItem.manage_options \
- + Cacheable.manage_options
-
-
- _properties=({'id':'title', 'type': 'ustring', 'mode': 'w'},
- {'id':'content_type', 'type':'string', 'mode': 'w'},
- {'id':'expand', 'type':'boolean', 'mode': 'w'},
- )
-
- security = AccessControl.ClassSecurityInfo()
- security.declareObjectProtected(view)
- security.declareProtected(view, '__call__')
-
- def __init__(self, id, text=None, content_type=None, encoding='utf-8'):
- self.id = id
- self.ZBindings_edit(self._default_bindings)
- self.pt_edit(text, content_type, encoding)
-
- security.declareProtected(change_page_templates, 'pt_encoding')
- def pt_encoding(self):
- encoding = sniffEncoding(self.read())
- return encoding
-
- # Use the encoding of the document as encoding for the ZMI to
- # avoid any kind of encoding troubles
- from ComputedAttribute import ComputedAttribute
- management_page_charset = ComputedAttribute(pt_encoding, 1)
-
- security.declareProtected(change_page_templates, 'pt_edit')
- def pt_edit(self, text, content_type, encoding='utf-8'):
-
- text = text.strip()
-# if content_type == 'text/html':
-# if not text.startswith('<?xml'):
-# # not XHTML -> convert it to unicode
-# text = unicode(text, encoding)
-
- if not isinstance(text, unicode):
- text = unicode(text, encoding)
-
- self.ZCacheable_invalidate()
- import pdb
- pdb.set_trace()
- PageTemplate.pt_edit(self, text, content_type)
-
- security.declareProtected(change_page_templates, 'pt_editAction')
- def pt_editAction(self, REQUEST, title, text, content_type, encoding, expand):
- """Change the title and document."""
-
- if self.wl_isLocked():
- raise ResourceLockedError("File is locked via WebDAV")
-
- self.expand = expand
- self.pt_setTitle(title, encoding)
-
- self.pt_edit(text, content_type, encoding)
- REQUEST.set('text', self.read()) # May not equal 'text'!
- REQUEST.set('title', self.title)
- message = "Saved changes."
- if getattr(self, '_v_warnings', None):
- message = ("<strong>Warning:</strong> <i>%s</i>"
- % '<br>'.join(self._v_warnings))
- return self.pt_editForm(manage_tabs_message=message)
-
-
- security.declareProtected(change_page_templates, 'pt_setTitle')
- def pt_setTitle(self, title, encoding='utf-8'):
- if not isinstance(title, unicode):
- title = unicode(title, encoding)
- self._setPropValue('title', title)
-
-
- def _setPropValue(self, id, value):
- """ set a property and invalidate the cache """
- PropertyManager._setPropValue(self, id, value)
- self.ZCacheable_invalidate()
-
-
- security.declareProtected(change_page_templates, 'pt_upload')
- def pt_upload(self, REQUEST, file='', encoding='utf-8'):
- """Replace the document with the text in file."""
-
- if self.wl_isLocked():
- raise ResourceLockedError("File is locked via WebDAV")
-
- if isinstance(file, str):
- filename = None
- text = file
- else:
- if not file:
- raise ValueError('File not specified')
- filename = file.filename
- text = file.read()
-
- content_type, dummy = guess_content_type(filename, text)
- if not content_type in ('text/html', 'text/xml'):
- raise ValueError('Unsupported mimetype: %s' % content_type)
-
- encoding = sniffEncoding(text, encoding)
- self.pt_edit(text, content_type, encoding)
- return self.pt_editForm(manage_tabs_message='Saved changes')
-
- security.declareProtected(change_page_templates, 'pt_changePrefs')
- def pt_changePrefs(self, REQUEST, height=None, width=None,
- dtpref_cols="100%", dtpref_rows="20"):
- """Change editing preferences."""
- dr = {"Taller":5, "Shorter":-5}.get(height, 0)
- dc = {"Wider":5, "Narrower":-5}.get(width, 0)
- if isinstance(height, int): dtpref_rows = height
- if isinstance(width, int) or \
- isinstance(width, str) and width.endswith('%'):
- dtpref_cols = width
- rows = str(max(1, int(dtpref_rows) + dr))
- cols = str(dtpref_cols)
- if cols.endswith('%'):
- cols = str(min(100, max(25, int(cols[:-1]) + dc))) + '%'
- else:
- cols = str(max(35, int(cols) + dc))
- e = (DateTime("GMT") + 365).rfc822()
- setCookie = REQUEST["RESPONSE"].setCookie
- setCookie("dtpref_rows", rows, path='/', expires=e)
- setCookie("dtpref_cols", cols, path='/', expires=e)
- REQUEST.other.update({"dtpref_cols":cols, "dtpref_rows":rows})
- return self.manage_main()
-
- def ZScriptHTML_tryParams(self):
- """Parameters to test the script with."""
- return []
-
-# def manage_historyCompare(self, rev1, rev2, REQUEST,
-# historyComparisonResults=''):
-# return ZopePageTemplate.inheritedAttribute(
-# 'manage_historyCompare')(
-# self, rev1, rev2, REQUEST,
-# historyComparisonResults=html_diff(rev1._text, rev2._text) )
-
- def pt_getContext(self, *args, **kw):
- root = self.getPhysicalRoot()
- context = self._getContext()
- c = {'template': self,
- 'here': context,
- 'context': context,
- 'container': self._getContainer(),
- 'nothing': None,
- 'options': {},
- 'root': root,
- 'request': getattr(root, 'REQUEST', None),
- 'modules': SecureModuleImporter,
- }
- return c
-
- security.declareProtected(view_management_screens, 'manage_main', 'read',
- 'ZScriptHTML_tryForm')
-
- def _exec(self, bound_names, args, kw):
- """Call a Page Template"""
- if not kw.has_key('args'):
- kw['args'] = args
- bound_names['options'] = kw
-
- try:
- response = self.REQUEST.RESPONSE
- if not response.headers.has_key('content-type'):
- response.setHeader('content-type', self.content_type)
- except AttributeError:
- pass
-
- security=getSecurityManager()
- bound_names['user'] = security.getUser()
-
- # Retrieve the value from the cache.
- keyset = None
- if self.ZCacheable_isCachingEnabled():
- # Prepare a cache key.
- keyset = {'here': self._getContext(),
- 'bound_names': bound_names}
- result = self.ZCacheable_get(keywords=keyset)
- if result is not None:
- # Got a cached value.
- return result
-
- # Execute the template in a new security context.
- security.addContext(self)
-
- try:
- # XXX: check the parameters for pt_render()! (aj)
- import pdb
- pdb.set_trace()
- result = self.pt_render(self.pt_getContext())
-
-# result = self.pt_render(extra_context=bound_names)
- if keyset is not None:
- # Store the result in the cache.
- self.ZCacheable_set(result, keywords=keyset)
- return result
- finally:
- security.removeContext(self)
-
- security.declareProtected(change_page_templates,
- 'manage_historyCopy',
- 'manage_beforeHistoryCopy', 'manage_afterHistoryCopy')
-
- security.declareProtected(change_page_templates, 'PUT')
- def PUT(self, REQUEST, RESPONSE):
- """ Handle HTTP PUT requests """
- self.dav__init(REQUEST, RESPONSE)
- self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
- ## XXX:this should be unicode or we must pass an encoding
- self.pt_edit(REQUEST.get('BODY', ''))
- RESPONSE.setStatus(204)
- return RESPONSE
-
- security.declareProtected(change_page_templates, 'manage_FTPput')
- manage_FTPput = PUT
-
- security.declareProtected(ftp_access, 'manage_FTPstat','manage_FTPlist')
-
- security.declareProtected(ftp_access, 'manage_FTPget')
- def manage_FTPget(self):
- "Get source for FTP download"
- self.REQUEST.RESPONSE.setHeader('Content-Type', self.content_type)
- return self.read()
-
- security.declareProtected(view_management_screens, 'html')
- def html(self):
- return self.content_type == 'text/html'
-
- security.declareProtected(view_management_screens, 'get_size')
- def get_size(self):
- return len(self.read())
-
- security.declareProtected(view_management_screens, 'getSize')
- getSize = get_size
-
- security.declareProtected(view_management_screens, 'PrincipiaSearchSource')
- def PrincipiaSearchSource(self):
- "Support for searching - the document's contents are searched."
- return self.read()
-
- security.declareProtected(view_management_screens, 'document_src')
- def document_src(self, REQUEST=None, RESPONSE=None):
- """Return expanded document source."""
-
- print 'src', self.read()
-
-
- if RESPONSE is not None:
- RESPONSE.setHeader('Content-Type', 'text/plain')
- if REQUEST is not None and REQUEST.get('raw'):
- return self._text
- return self.read()
-
- def om_icons(self):
- """Return a list of icon URLs to be displayed by an ObjectManager"""
- icons = ({'path': 'misc_/PageTemplates/zpt.gif',
- 'alt': self.meta_type, 'title': self.meta_type},)
- if not self._v_cooked:
- self._cook()
- if self._v_errors:
- icons = icons + ({'path': 'misc_/PageTemplates/exclamation.gif',
- 'alt': 'Error',
- 'title': 'This template has an error'},)
- return icons
-
- security.declareProtected(view, 'pt_source_file')
- def pt_source_file(self):
- """Returns a file name to be compiled into the TAL code."""
- try:
- return '/'.join(self.getPhysicalPath())
- except:
- # This page template is being compiled without an
- # acquisition context, so we don't know where it is. :-(
- return None
-
- def wl_isLocked(self):
- return 0
-
- security.declareProtected(view_management_screens, 'getSource')
- getSource = Src()
- source_dot_xml = Src()
-
-InitializeClass(ZPT)
-
-
-setattr(ZPT, 'source.xml', ZPT.source_dot_xml)
-setattr(ZPT, 'source.html', ZPT.source_dot_xml)
-
-
-def _newZPT(id, filename):
- """ factory to generate ZPT instances from the file-system
- based templates (basically for internal purposes)
- """
- zpt = ZPT(id, open(filename).read(), 'text/html')
- zpt.__name__= id
- return zpt
-
-class FSZPT(ZPT):
- """ factory to generate ZPT instances from the file-system
- based templates (basically for internal purposes)
- """
-
- def __init__(self, id, filename):
- ZPT.__init__(self, id, open(filename).read(), 'text/html')
- self.__name__= id
-
-InitializeClass(FSZPT)
-
-
-ZPT.pt_editForm = FSZPT('pt_editForm', os.path.join(package_home(globals()),'pt', 'ptEdit.pt'))
-# this is scary, do we need this?
-ZPT.manage = ZPT.manage_main = ZPT.pt_editForm
-
-manage_addZPTForm= FSZPT('manage_addZPTForm', os.path.join(package_home(globals()), 'pt', 'ptAdd.pt'))
-
-def manage_addZPT(self, id, title='', file=None, encoding='utf-8', submit=None, RESPONSE=None):
- "Add a Page Template with optional file content."
-
- if file:
- filename = file.filename
- text = file.read()
- encoding = sniffEncoding(text)
- content_type, dummy = guess_content_type(filename, text)
- else:
- text = open(_default_content_fn).read()
- encoding = 'utf-8'
- content_type = 'text/html'
-
- zpt = ZPT(id, text, content_type, encoding)
- zpt.pt_setTitle(title, encoding)
- self._setObject(id, zpt)
- zpt = getattr(self, id)
-
- if RESPONSE:
- if submit == " Add and Edit ":
- RESPONSE.redirect(zpt.absolute_url() + '/manage_main')
- else:
- RESPONSE.redirect(self.absolute_url() + '/manage_main')
- else:
- return zpt
-
-from Products.ZPT import misc_
-misc_['exclamation.gif'] = ImageFile('pt/exclamation.gif', globals())
-
-def initialize(context):
- context.registerClass(
- ZPT,
- permission='Add Page Templates',
- constructors=(manage_addZPTForm,
- manage_addZPT),
- icon='pt/zpt.gif',
- )
- context.registerHelp()
- context.registerHelpTitle('Zope Help')
-
More information about the Zope-Checkins
mailing list