Back to index

plone3  3.1.7
FSDTMLMethod.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ Customizable DTML methods that come from the filesystem.
00014 
00015 $Id: FSDTMLMethod.py 77019 2007-06-24 19:01:14Z hannosch $
00016 """
00017 
00018 import Globals
00019 from AccessControl import ClassSecurityInfo
00020 from AccessControl import getSecurityManager
00021 from AccessControl.DTML import RestrictedDTML
00022 from AccessControl.Role import RoleManager
00023 from OFS.Cache import Cacheable
00024 from OFS.DTMLMethod import DTMLMethod, decapitate, guess_content_type
00025 
00026 from DirectoryView import registerFileExtension
00027 from DirectoryView import registerMetaType
00028 from FSObject import FSObject
00029 from permissions import FTPAccess
00030 from permissions import View
00031 from permissions import ViewManagementScreens
00032 from utils import _checkConditionalGET
00033 from utils import _dtmldir
00034 from utils import _setCacheHeaders
00035 
00036 _marker = object()
00037 
00038 
00039 class FSDTMLMethod(RestrictedDTML, RoleManager, FSObject, Globals.HTML):
00040 
00041     """FSDTMLMethods act like DTML methods but are not directly
00042     modifiable from the management interface.
00043     """
00044 
00045     meta_type = 'Filesystem DTML Method'
00046     _owner = None
00047     _proxy_roles = ()
00048     _cache_namespace_keys = ()
00049     _reading = 0
00050 
00051     manage_options=({'label':'Customize', 'action':'manage_main'},
00052                     {'label':'View', 'action':'',
00053                      'help':('OFSP','DTML-DocumentOrMethod_View.stx')},
00054                     {'label':'Proxy', 'action':'manage_proxyForm',
00055                      'help':('OFSP','DTML-DocumentOrMethod_Proxy.stx')},
00056                    )
00057 
00058     security = ClassSecurityInfo()
00059     security.declareObjectProtected(View)
00060 
00061     security.declareProtected(ViewManagementScreens, 'manage_main')
00062     manage_main = Globals.DTMLFile('custdtml', _dtmldir)
00063 
00064     def __init__(self, id, filepath, fullname=None, properties=None):
00065         FSObject.__init__(self, id, filepath, fullname, properties)
00066         # Normally called via HTML.__init__ but we don't need the rest that
00067         # happens there.
00068         self.initvars(None, {})
00069 
00070     def _createZODBClone(self):
00071         """Create a ZODB (editable) equivalent of this object."""
00072         return DTMLMethod(self.read(), __name__=self.getId())
00073 
00074     def _readFile(self, reparse):
00075         """Read the data from the filesystem.
00076         """
00077         file = open(self._filepath, 'r') # not 'rb', as this is a text file!
00078         try:
00079             data = file.read()
00080         finally:
00081             file.close()
00082         self.raw = data
00083 
00084         if reparse:
00085             self._reading = 1  # Avoid infinite recursion
00086             try:
00087                 self.cook()
00088             finally:
00089                 self._reading = 0
00090 
00091     # Hook up chances to reload in debug mode
00092     security.declarePrivate('read_raw')
00093     def read_raw(self):
00094         if not self._reading:
00095             self._updateFromFS()
00096         return Globals.HTML.read_raw(self)
00097 
00098     #### The following is mainly taken from OFS/DTMLMethod.py ###
00099 
00100     index_html=None # Prevent accidental acquisition
00101 
00102     # Documents masquerade as functions:
00103     func_code = DTMLMethod.func_code
00104 
00105     default_content_type = 'text/html'
00106 
00107     def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
00108         """Render the document given a client object, REQUEST mapping,
00109         Response, and key word arguments."""
00110 
00111         self._updateFromFS()
00112 
00113         kw['document_id']   =self.getId()
00114         kw['document_title']=self.title
00115 
00116         if client is not None:
00117             if _checkConditionalGET(self, kw):
00118                 return ''
00119 
00120         if not self._cache_namespace_keys:
00121             data = self.ZCacheable_get(default=_marker)
00122             if data is not _marker:
00123                 # Return cached results.
00124                 return data
00125 
00126         __traceback_info__ = self._filepath
00127         security=getSecurityManager()
00128         security.addContext(self)
00129         try:
00130             r = Globals.HTML.__call__(self, client, REQUEST, **kw)
00131 
00132             if client is None:
00133                 # Called as subtemplate, so don't need error propagation!
00134                 if RESPONSE is None: result = r
00135                 else: result = decapitate(r, RESPONSE)
00136                 if not self._cache_namespace_keys:
00137                     self.ZCacheable_set(result)
00138                 return result
00139 
00140             if not isinstance(r, basestring) or RESPONSE is None:
00141                 if not self._cache_namespace_keys:
00142                     self.ZCacheable_set(r)
00143                 return r
00144 
00145         finally: security.removeContext(self)
00146 
00147         have_key=RESPONSE.headers.has_key
00148         if not (have_key('content-type') or have_key('Content-Type')):
00149             if self.__dict__.has_key('content_type'):
00150                 c=self.content_type
00151             else:
00152                 c, e=guess_content_type(self.getId(), r)
00153             RESPONSE.setHeader('Content-Type', c)
00154         if RESPONSE is not None:
00155             # caching policy manager hook
00156             _setCacheHeaders(self, {})
00157         result = decapitate(r, RESPONSE)
00158         if not self._cache_namespace_keys:
00159             self.ZCacheable_set(result)
00160         return result
00161 
00162     def getCacheNamespaceKeys(self):
00163         '''
00164         Returns the cacheNamespaceKeys.
00165         '''
00166         return self._cache_namespace_keys
00167 
00168     def setCacheNamespaceKeys(self, keys, REQUEST=None):
00169         '''
00170         Sets the list of names that should be looked up in the
00171         namespace to provide a cache key.
00172         '''
00173         ks = []
00174         for key in keys:
00175             key = str(key).strip()
00176             if key:
00177                 ks.append(key)
00178         self._cache_namespace_keys = tuple(ks)
00179         if REQUEST is not None:
00180             return self.ZCacheable_manage(self, REQUEST)
00181 
00182     # Zope 2.3.x way:
00183     def validate(self, inst, parent, name, value, md=None):
00184         return getSecurityManager().validate(inst, parent, name, value)
00185 
00186     security.declareProtected(FTPAccess, 'manage_FTPget')
00187     manage_FTPget = DTMLMethod.manage_FTPget.im_func
00188 
00189     security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource')
00190     PrincipiaSearchSource = DTMLMethod.PrincipiaSearchSource.im_func
00191 
00192     security.declareProtected(ViewManagementScreens, 'document_src')
00193     document_src = DTMLMethod.document_src.im_func
00194 
00195     security.declareProtected(ViewManagementScreens, 'manage_haveProxy')
00196     manage_haveProxy = DTMLMethod.manage_haveProxy.im_func
00197 
00198 Globals.InitializeClass(FSDTMLMethod)
00199 
00200 registerFileExtension('dtml', FSDTMLMethod)
00201 registerMetaType('DTML Method', FSDTMLMethod)