[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