Commit dbb476e6 authored by Hanno Schlichting's avatar Hanno Schlichting

Remove ZCacheable logic and StandardCacheManagers dependency.

parent dabb9766
...@@ -30,6 +30,8 @@ Features Added ...@@ -30,6 +30,8 @@ Features Added
Restructuring Restructuring
+++++++++++++ +++++++++++++
- Remove ZCacheable logic and StandardCacheManagers dependency.
- Stop mixing in `Five.bbb.AcquisitionBBB` into browser components. - Stop mixing in `Five.bbb.AcquisitionBBB` into browser components.
- Integrate `five.pt` code directly into `Products.PageTemplates`. - Integrate `five.pt` code directly into `Products.PageTemplates`.
...@@ -309,5 +311,4 @@ Restructuring ...@@ -309,5 +311,4 @@ Restructuring
``Products.SiteErrorLog`` ``Products.SiteErrorLog``
``Products.StandardCacheManagers`` ``Products.StandardCacheManagers``
``Products.ZCatalog`` ``Products.ZCatalog``
``Products.ZCTextIndex``
``Record`` ``Record``
...@@ -72,7 +72,6 @@ eggs = ...@@ -72,7 +72,6 @@ eggs =
Products.PythonScripts Products.PythonScripts
Products.Sessions Products.Sessions
Products.SiteErrorLog Products.SiteErrorLog
Products.StandardCacheManagers
Products.TemporaryFolder Products.TemporaryFolder
Products.ZCatalog Products.ZCatalog
Record Record
......
...@@ -25,7 +25,6 @@ Products.MailHost = git ${remotes:github}/Products.MailHost pushurl=${remotes:gi ...@@ -25,7 +25,6 @@ Products.MailHost = git ${remotes:github}/Products.MailHost pushurl=${remotes:gi
Products.PythonScripts = git ${remotes:github}/Products.PythonScripts pushurl=${remotes:github_push}/Products.PythonScripts Products.PythonScripts = git ${remotes:github}/Products.PythonScripts pushurl=${remotes:github_push}/Products.PythonScripts
Products.Sessions = git ${remotes:github}/Products.Sessions.git pushurl=${remotes:github_push}/Products.Sessions Products.Sessions = git ${remotes:github}/Products.Sessions.git pushurl=${remotes:github_push}/Products.Sessions
Products.SiteErrorLog = git ${remotes:github}/Products.SiteErrorLog pushurl=${remotes:github_push}/Products.SiteErrorLog Products.SiteErrorLog = git ${remotes:github}/Products.SiteErrorLog pushurl=${remotes:github_push}/Products.SiteErrorLog
Products.StandardCacheManagers = git ${remotes:github}/Products.StandardCacheManagers pushurl=${remotes:github_push}/Products.StandardCacheManagers
Products.TemporaryFolder = git ${remotes:github}/Products.TemporaryFolder pushurl=${remotes:github_push}/Products.TemporaryFolder branch=master Products.TemporaryFolder = git ${remotes:github}/Products.TemporaryFolder pushurl=${remotes:github_push}/Products.TemporaryFolder branch=master
Products.ZCatalog = git ${remotes:github}/Products.ZCatalog pushurl=${remotes:github_push}/Products.ZCatalog branch=master Products.ZCatalog = git ${remotes:github}/Products.ZCatalog pushurl=${remotes:github_push}/Products.ZCatalog branch=master
Products.ZCTextIndex = git ${remotes:github}/Products.ZCTextIndex pushurl=${remotes:github_push}/Products.ZCTextIndex Products.ZCTextIndex = git ${remotes:github}/Products.ZCTextIndex pushurl=${remotes:github_push}/Products.ZCTextIndex
......
...@@ -14,20 +14,10 @@ ...@@ -14,20 +14,10 @@
""" """
from logging import getLogger from logging import getLogger
import sys
import time
from AccessControl.class_init import InitializeClass from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import view_management_screens from AccessControl.Permissions import view_management_screens
from AccessControl.SecurityInfo import ClassSecurityInfo from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.unauthorized import Unauthorized
from Acquisition import aq_acquire
from Acquisition import aq_base
from Acquisition import aq_get
from Acquisition import aq_inner
from Acquisition import aq_parent
from App.special_dtml import DTMLFile
ZCM_MANAGERS = '__ZCacheManager_ids__' ZCM_MANAGERS = '__ZCacheManager_ids__'
...@@ -37,18 +27,16 @@ LOG = getLogger('Cache') ...@@ -37,18 +27,16 @@ LOG = getLogger('Cache')
def isCacheable(ob): def isCacheable(ob):
return getattr(aq_base(ob), '_isCacheable', 0) return False
def managersExist(ob): def managersExist(ob):
# Returns 1 if any CacheManagers exist in the context of ob. # Returns 1 if any CacheManagers exist in the context of ob.
if aq_get(ob, ZCM_MANAGERS, None, 1): return False
return 1
return 0
def filterCacheTab(ob): def filterCacheTab(ob):
return managersExist(ob) return False
def filterCacheManagers(orig, container, name, value, extra): def filterCacheManagers(orig, container, name, value, extra):
...@@ -57,22 +45,14 @@ def filterCacheManagers(orig, container, name, value, extra): ...@@ -57,22 +45,14 @@ def filterCacheManagers(orig, container, name, value, extra):
It causes objects to be found only if they are It causes objects to be found only if they are
in the list of cache managers. in the list of cache managers.
''' '''
if (hasattr(aq_base(container), ZCM_MANAGERS) and return False
name in getattr(container, ZCM_MANAGERS)):
return 1
return 0
def getVerifiedManagerIds(container): def getVerifiedManagerIds(container):
''' '''
Gets the list of cache managers in a container, verifying each one. Gets the list of cache managers in a container, verifying each one.
''' '''
ids = getattr(container, ZCM_MANAGERS, ()) return ()
rval = []
for id in ids:
if getattr(getattr(container, id, None), '_isCacheManager', 0):
rval.append(id)
return tuple(rval)
# Anytime a CacheManager is added or removed, all _v_ZCacheable_cache # Anytime a CacheManager is added or removed, all _v_ZCacheable_cache
...@@ -81,61 +61,31 @@ def getVerifiedManagerIds(container): ...@@ -81,61 +61,31 @@ def getVerifiedManagerIds(container):
manager_timestamp = 0 manager_timestamp = 0
class Cacheable: class Cacheable(object):
'''Mix-in for cacheable objects. '''Mix-in for cacheable objects.
''' '''
manage_options = ( manage_options = ()
{'label': 'Cache', 'action': 'ZCacheable_manage',
'filter': filterCacheTab},
)
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.setPermissionDefault(ChangeCacheSettingsPermission, ('Manager',)) security.setPermissionDefault(ChangeCacheSettingsPermission, ('Manager',))
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_manage')
ZCacheable_manage = DTMLFile('dtml/cacheable', globals())
_v_ZCacheable_cache = None _v_ZCacheable_cache = None
_v_ZCacheable_manager_timestamp = 0 _v_ZCacheable_manager_timestamp = 0
__manager_id = None __manager_id = None
__enabled = 1 __enabled = False
_isCacheable = 1 _isCacheable = False
security.declarePrivate('ZCacheable_getManager') security.declarePrivate('ZCacheable_getManager')
def ZCacheable_getManager(self): def ZCacheable_getManager(self):
'''Returns the currently associated cache manager.''' '''Returns the currently associated cache manager.'''
manager_id = self.__manager_id return None
if manager_id is None:
return None
try:
return aq_acquire(
self, manager_id, containment=1,
filter=filterCacheManagers, extra=None, default=None)
except AttributeError:
return None
security.declarePrivate('ZCacheable_getCache') security.declarePrivate('ZCacheable_getCache')
def ZCacheable_getCache(self): def ZCacheable_getCache(self):
'''Gets the cache associated with this object. '''Gets the cache associated with this object.
''' '''
if self.__manager_id is None: return None
return None
c = self._v_ZCacheable_cache
if c is not None:
# We have a volatile reference to the cache.
if self._v_ZCacheable_manager_timestamp == manager_timestamp:
return aq_base(c)
manager = self.ZCacheable_getManager()
if manager is not None:
c = aq_base(manager.ZCacheManager_getCache())
else:
return None
# Set a volatile reference to the cache then return it.
self._v_ZCacheable_cache = c
self._v_ZCacheable_manager_timestamp = manager_timestamp
return c
security.declarePrivate('ZCacheable_isCachingEnabled') security.declarePrivate('ZCacheable_isCachingEnabled')
def ZCacheable_isCachingEnabled(self): def ZCacheable_isCachingEnabled(self):
...@@ -143,7 +93,7 @@ class Cacheable: ...@@ -143,7 +93,7 @@ class Cacheable:
Returns true only if associated with a cache manager and Returns true only if associated with a cache manager and
caching of this method is enabled. caching of this method is enabled.
''' '''
return self.__enabled and self.ZCacheable_getCache() return False
security.declarePrivate('ZCacheable_getObAndView') security.declarePrivate('ZCacheable_getObAndView')
def ZCacheable_getObAndView(self, view_name): def ZCacheable_getObAndView(self, view_name):
...@@ -157,16 +107,6 @@ class Cacheable: ...@@ -157,16 +107,6 @@ class Cacheable:
conditions specified by keywords. If the value is conditions specified by keywords. If the value is
not yet cached, returns the default. not yet cached, returns the default.
''' '''
c = self.ZCacheable_getCache()
if c is not None and self.__enabled:
ob, view_name = self.ZCacheable_getObAndView(view_name)
try:
val = c.ZCache_get(ob, view_name, keywords,
mtime_func, default)
return val
except:
LOG.warn('ZCache_get() exception')
return default
return default return default
security.declarePrivate('ZCacheable_set') security.declarePrivate('ZCacheable_set')
...@@ -175,14 +115,7 @@ class Cacheable: ...@@ -175,14 +115,7 @@ class Cacheable:
'''Cacheable views should call this method after generating '''Cacheable views should call this method after generating
cacheable results. The data argument can be of any Python type. cacheable results. The data argument can be of any Python type.
''' '''
c = self.ZCacheable_getCache() pass
if c is not None and self.__enabled:
ob, view_name = self.ZCacheable_getObAndView(view_name)
try:
c.ZCache_set(ob, data, view_name, keywords,
mtime_func)
except:
LOG.warn('ZCache_set() exception')
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_invalidate') 'ZCacheable_invalidate')
...@@ -191,60 +124,23 @@ class Cacheable: ...@@ -191,60 +124,23 @@ class Cacheable:
cache entries that apply to the view_name to be removed. cache entries that apply to the view_name to be removed.
Returns a status message. Returns a status message.
''' '''
c = self.ZCacheable_getCache() pass
if c is not None:
ob, view_name = self.ZCacheable_getObAndView(view_name)
try:
message = c.ZCache_invalidate(ob)
if not message:
message = 'Invalidated.'
except:
exc = sys.exc_info()
try:
LOG.warn('ZCache_invalidate() exception')
message = 'An exception occurred: %s: %s' % exc[:2]
finally:
exc = None
else:
message = 'This object is not associated with a cache manager.'
if REQUEST is not None:
return self.ZCacheable_manage(
self, REQUEST, management_view='Cache',
manage_tabs_message=message)
else:
return message
security.declarePrivate('ZCacheable_getModTime') security.declarePrivate('ZCacheable_getModTime')
def ZCacheable_getModTime(self, mtime_func=None): def ZCacheable_getModTime(self, mtime_func=None):
'''Returns the highest of the last mod times.''' '''Returns the highest of the last mod times.'''
# Based on: return 0
# mtime_func
# self.mtime
# self.__class__.mtime
mtime = 0
if mtime_func:
# Allow mtime_func to influence the mod time.
mtime = mtime_func()
base = aq_base(self)
mtime = max(getattr(base, '_p_mtime', mtime), mtime)
klass = getattr(base, '__class__', None)
if klass:
mtime = max(getattr(klass, '_p_mtime', mtime), mtime)
return mtime
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_getManagerId') 'ZCacheable_getManagerId')
def ZCacheable_getManagerId(self): def ZCacheable_getManagerId(self):
'''Returns the id of the current ZCacheManager.''' '''Returns the id of the current ZCacheManager.'''
return self.__manager_id return None
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_getManagerURL') 'ZCacheable_getManagerURL')
def ZCacheable_getManagerURL(self): def ZCacheable_getManagerURL(self):
'''Returns the URL of the current ZCacheManager.''' '''Returns the URL of the current ZCacheManager.'''
manager = self.ZCacheable_getManager()
if manager is not None:
return manager.absolute_url()
return None return None
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
...@@ -252,120 +148,31 @@ class Cacheable: ...@@ -252,120 +148,31 @@ class Cacheable:
def ZCacheable_getManagerIds(self): def ZCacheable_getManagerIds(self):
'''Returns a list of mappings containing the id and title '''Returns a list of mappings containing the id and title
of the available ZCacheManagers.''' of the available ZCacheManagers.'''
rval = [] return ()
ob = self
used_ids = {}
while ob is not None:
if hasattr(aq_base(ob), ZCM_MANAGERS):
ids = getattr(ob, ZCM_MANAGERS)
for id in ids:
manager = getattr(ob, id, None)
if manager is not None:
id = manager.getId()
if id not in used_ids:
title = getattr(aq_base(manager), 'title', '')
rval.append({'id': id, 'title': title})
used_ids[id] = 1
ob = aq_parent(aq_inner(ob))
return tuple(rval)
security.declareProtected(ChangeCacheSettingsPermission, security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheable_setManagerId') 'ZCacheable_setManagerId')
def ZCacheable_setManagerId(self, manager_id, REQUEST=None): def ZCacheable_setManagerId(self, manager_id, REQUEST=None):
'''Changes the manager_id for this object.''' '''Changes the manager_id for this object.'''
self.ZCacheable_invalidate() pass
if not manager_id:
# User requested disassociation
# from the cache manager.
manager_id = None
else:
manager_id = str(manager_id)
self.__manager_id = manager_id
self._v_ZCacheable_cache = None
if REQUEST is not None:
return self.ZCacheable_manage(
self, REQUEST, management_view='Cache',
manage_tabs_message='Cache settings changed.')
security.declareProtected(ViewManagementScreensPermission, security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_enabled') 'ZCacheable_enabled')
def ZCacheable_enabled(self): def ZCacheable_enabled(self):
'''Returns true if caching is enabled for this object '''Returns true if caching is enabled for this object
or method.''' or method.'''
return self.__enabled return False
security.declareProtected(ChangeCacheSettingsPermission, security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheable_setEnabled') 'ZCacheable_setEnabled')
def ZCacheable_setEnabled(self, enabled=0, REQUEST=None): def ZCacheable_setEnabled(self, enabled=0, REQUEST=None):
'''Changes the enabled flag.''' '''Changes the enabled flag.'''
self.__enabled = enabled and 1 or 0 pass
if REQUEST is not None:
return self.ZCacheable_manage(
self, REQUEST, management_view='Cache',
manage_tabs_message='Cache settings changed.')
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_configHTML')
def ZCacheable_configHTML(self):
'''Override to provide configuration of caching
behavior that can only be specific to the cacheable object.
'''
return ''
InitializeClass(Cacheable) InitializeClass(Cacheable)
def findCacheables(ob, manager_id, require_assoc, subfolders,
meta_types, rval, path):
'''
Used by the CacheManager UI. Recursive. Similar to the Zope
"Find" function. Finds all Cacheable objects in a hierarchy.
'''
try:
if meta_types:
subobs = ob.objectValues(meta_types)
else:
subobs = ob.objectValues()
sm = getSecurityManager()
# Add to the list of cacheable objects.
for subob in subobs:
if not isCacheable(subob):
continue
associated = (subob.ZCacheable_getManagerId() == manager_id)
if require_assoc and not associated:
continue
if not sm.checkPermission('Change cache settings', subob):
continue
subpath = path + (subob.getId(),)
info = {
'sortkey': subpath,
'path': '/'.join(subpath),
'title': getattr(aq_base(subob), 'title', ''),
'icon': None,
'associated': associated,
}
rval.append(info)
# Visit subfolders.
if subfolders:
if meta_types:
subobs = ob.objectValues()
for subob in subobs:
subpath = path + (subob.getId(),)
if hasattr(aq_base(subob), 'objectValues'):
if sm.checkPermission(
'Access contents information', subob):
findCacheables(
subob, manager_id, require_assoc,
subfolders, meta_types, rval, subpath)
except:
# Ignore exceptions.
import traceback
traceback.print_exc()
class Cache: class Cache:
''' '''
A base class (and interface description) for caches. A base class (and interface description) for caches.
...@@ -414,37 +221,15 @@ class CacheManager: ...@@ -414,37 +221,15 @@ class CacheManager:
_isCacheManager = 1 _isCacheManager = 1
manage_options = ( manage_options = ()
{'label': 'Associate', 'action': 'ZCacheManager_associate'},
)
def manage_afterAdd(self, item, container): def manage_afterAdd(self, item, container):
# Adds self to the list of cache managers in the container. # Adds self to the list of cache managers in the container.
if aq_base(self) is aq_base(item): pass
ids = getVerifiedManagerIds(container)
id = self.getId()
if id not in ids:
setattr(container, ZCM_MANAGERS, ids + (id,))
global manager_timestamp
manager_timestamp = time.time()
def manage_beforeDelete(self, item, container): def manage_beforeDelete(self, item, container):
# Removes self from the list of cache managers. # Removes self from the list of cache managers.
if aq_base(self) is aq_base(item): pass
ids = getVerifiedManagerIds(container)
id = self.getId()
if id in ids:
manager_ids = [s for s in ids if s != id]
if manager_ids:
setattr(container, ZCM_MANAGERS, manager_ids)
elif getattr(aq_base(self), ZCM_MANAGERS, None) is not None:
delattr(self, ZCM_MANAGERS)
global manager_timestamp
manager_timestamp = time.time()
security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheManager_associate')
ZCacheManager_associate = DTMLFile('dtml/cmassoc', globals())
security.declareProtected(ChangeCacheSettingsPermission, security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheManager_locate') 'ZCacheManager_locate')
...@@ -452,20 +237,7 @@ class CacheManager: ...@@ -452,20 +237,7 @@ class CacheManager:
meta_types=[], REQUEST=None): meta_types=[], REQUEST=None):
'''Locates cacheable objects. '''Locates cacheable objects.
''' '''
ob = aq_parent(aq_inner(self)) return []
rval = []
manager_id = self.getId()
if '' in meta_types:
# User selected "All".
meta_types = []
findCacheables(ob, manager_id, require_assoc, subfolders,
meta_types, rval, ())
if REQUEST is not None:
return self.ZCacheManager_associate(
self, REQUEST, show_results=1, results=rval,
management_view="Associate")
else:
return rval
security.declareProtected(ChangeCacheSettingsPermission, security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheManager_setAssociations') 'ZCacheManager_setAssociations')
...@@ -473,36 +245,6 @@ class CacheManager: ...@@ -473,36 +245,6 @@ class CacheManager:
'''Associates and un-associates cacheable objects with this '''Associates and un-associates cacheable objects with this
cache manager. cache manager.
''' '''
addcount = 0 pass
remcount = 0
parent = aq_parent(aq_inner(self))
sm = getSecurityManager()
my_id = str(self.getId())
if props is None:
props = REQUEST.form
for key, do_associate in props.items():
if key[:10] == 'associate_':
path = key[10:]
ob = parent.restrictedTraverse(path)
if not sm.checkPermission('Change cache settings', ob):
raise Unauthorized
if not isCacheable(ob):
# Not a cacheable object.
continue
manager_id = str(ob.ZCacheable_getManagerId())
if do_associate:
if manager_id != my_id:
ob.ZCacheable_setManagerId(my_id)
addcount = addcount + 1
else:
if manager_id == my_id:
ob.ZCacheable_setManagerId(None)
remcount = remcount + 1
if REQUEST is not None:
return self.ZCacheManager_associate(
self, REQUEST, management_view="Associate",
manage_tabs_message='%d association(s) made, %d removed.' %
(addcount, remcount)
)
InitializeClass(CacheManager) InitializeClass(CacheManager)
...@@ -59,7 +59,6 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -59,7 +59,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
file = file.read() file = file.read()
self.munge(file) self.munge(file)
self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message = "Content uploaded." message = "Content uploaded."
return self.manage_main(self, REQUEST, manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
...@@ -69,12 +68,6 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -69,12 +68,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
o If supplied, use REQUEST mapping, Response, and key word arguments. o If supplied, use REQUEST mapping, Response, and key word arguments.
""" """
if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker)
if data is not _marker:
# Return cached results.
return data
__traceback_supplement__ = (PathTracebackSupplement, self) __traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] = self.getId() kw['document_id'] = self.getId()
kw['document_title'] = self.title kw['document_title'] = self.title
...@@ -94,15 +87,11 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -94,15 +87,11 @@ class DTMLDocument(PropertyManager, DTMLMethod):
result = r result = r
else: else:
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result return result
r = HTML.__call__(self, (client, bself), REQUEST, **kw) r = HTML.__call__(self, (client, bself), REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str): if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r return r
finally: finally:
...@@ -116,8 +105,6 @@ class DTMLDocument(PropertyManager, DTMLMethod): ...@@ -116,8 +105,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
c, e = guess_content_type(self.__name__, r) c, e = guess_content_type(self.__name__, r)
RESPONSE.setHeader('Content-Type', c) RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result return result
......
...@@ -36,7 +36,6 @@ from OFS.role import RoleManager ...@@ -36,7 +36,6 @@ from OFS.role import RoleManager
from OFS.SimpleItem import Item_w__name__ from OFS.SimpleItem import Item_w__name__
from zExceptions import Forbidden, ResourceLockedError from zExceptions import Forbidden, ResourceLockedError
from zExceptions.TracebackSupplement import PathTracebackSupplement from zExceptions.TracebackSupplement import PathTracebackSupplement
from ZPublisher.Iterators import IStreamIterator
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
if sys.version_info >= (3, ): if sys.version_info >= (3, ):
...@@ -49,14 +48,13 @@ class DTMLMethod(RestrictedDTML, ...@@ -49,14 +48,13 @@ class DTMLMethod(RestrictedDTML,
HTML, HTML,
Implicit, Implicit,
RoleManager, RoleManager,
Item_w__name__, Cacheable,
Cacheable): Item_w__name__):
""" DocumentTemplate.HTML objects that act as methods of their containers. """ DocumentTemplate.HTML objects that act as methods of their containers.
""" """
meta_type = 'DTML Method' meta_type = 'DTML Method'
_proxy_roles = () _proxy_roles = ()
index_html = None # Prevent accidental acquisition index_html = None # Prevent accidental acquisition
_cache_namespace_keys = ()
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(View) security.declareObjectProtected(View)
...@@ -74,8 +72,7 @@ class DTMLMethod(RestrictedDTML, ...@@ -74,8 +72,7 @@ class DTMLMethod(RestrictedDTML,
{'label': 'Proxy', 'action': 'manage_proxyForm'}, {'label': 'Proxy', 'action': 'manage_proxyForm'},
) + ) +
RoleManager.manage_options + RoleManager.manage_options +
Item_w__name__.manage_options + Item_w__name__.manage_options
Cacheable.manage_options
) )
# More reasonable default for content-type for http HEAD requests. # More reasonable default for content-type for http HEAD requests.
...@@ -91,27 +88,6 @@ class DTMLMethod(RestrictedDTML, ...@@ -91,27 +88,6 @@ class DTMLMethod(RestrictedDTML,
o If supplied, use the REQUEST mapping, Response, and key word o If supplied, use the REQUEST mapping, Response, and key word
arguments. arguments.
""" """
if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker)
if data is not _marker:
if (IStreamIterator.isImplementedBy(data) and
RESPONSE is not None):
# This is a stream iterator and we need to set some
# headers now before giving it to medusa
headers_get = RESPONSE.headers.get
if headers_get('content-length', None) is None:
RESPONSE.setHeader('content-length', len(data))
if (headers_get('content-type', None) is None and
headers_get('Content-type', None) is None):
ct = (self.__dict__.get('content_type') or
self.default_content_type)
RESPONSE.setHeader('content-type', ct)
# Return cached results.
return data
__traceback_supplement__ = (PathTracebackSupplement, self) __traceback_supplement__ = (PathTracebackSupplement, self)
kw['document_id'] = self.getId() kw['document_id'] = self.getId()
kw['document_title'] = self.title kw['document_title'] = self.title
...@@ -132,14 +108,10 @@ class DTMLMethod(RestrictedDTML, ...@@ -132,14 +108,10 @@ class DTMLMethod(RestrictedDTML,
result = r result = r
else: else:
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result return result
r = HTML.__call__(self, client, REQUEST, **kw) r = HTML.__call__(self, client, REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str): if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r return r
finally: finally:
...@@ -155,59 +127,24 @@ class DTMLMethod(RestrictedDTML, ...@@ -155,59 +127,24 @@ class DTMLMethod(RestrictedDTML,
c, e = guess_content_type(self.getId(), r) c, e = guess_content_type(self.getId(), r)
RESPONSE.setHeader('Content-Type', c) RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE) result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result return result
def validate(self, inst, parent, name, value, md=None): def validate(self, inst, parent, name, value, md=None):
return getSecurityManager().validate(inst, parent, name, value) return getSecurityManager().validate(inst, parent, name, value)
def ZDocumentTemplate_beforeRender(self, md, default): def ZDocumentTemplate_beforeRender(self, md, default):
# Tries to get a cached value.
if self._cache_namespace_keys:
# Use the specified keys from the namespace to identify a
# cache entry.
kw = {}
for key in self._cache_namespace_keys:
try:
val = md[key]
except:
val = None
kw[key] = val
return self.ZCacheable_get(keywords=kw, default=default)
return default return default
def ZDocumentTemplate_afterRender(self, md, result): def ZDocumentTemplate_afterRender(self, md, result):
# Tries to set a cache value. pass
if self._cache_namespace_keys:
kw = {}
for key in self._cache_namespace_keys:
try:
val = md[key]
except:
val = None
kw[key] = val
self.ZCacheable_set(result, keywords=kw)
security.declareProtected(change_dtml_methods, 'ZCacheable_configHTML')
ZCacheable_configHTML = DTMLFile('dtml/cacheNamespaceKeys', globals())
security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys') security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys')
def getCacheNamespaceKeys(self): def getCacheNamespaceKeys(self):
# Return the cacheNamespaceKeys. return ()
return self._cache_namespace_keys
security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys') security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys')
def setCacheNamespaceKeys(self, keys, REQUEST=None): def setCacheNamespaceKeys(self, keys, REQUEST=None):
# Set the list of names looked up to provide a cache key. pass
ks = []
for key in keys:
key = str(key).strip()
if key:
ks.append(key)
self._cache_namespace_keys = tuple(ks)
if REQUEST is not None:
return self.ZCacheable_manage(self, REQUEST)
security.declareProtected(View, 'get_size') security.declareProtected(View, 'get_size')
def get_size(self): def get_size(self):
...@@ -245,7 +182,6 @@ class DTMLMethod(RestrictedDTML, ...@@ -245,7 +182,6 @@ class DTMLMethod(RestrictedDTML,
if not isinstance(data, basestring): if not isinstance(data, basestring):
data = data.read() data = data.read()
self.munge(data) self.munge(data)
self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message = "Saved changes." message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
...@@ -264,7 +200,6 @@ class DTMLMethod(RestrictedDTML, ...@@ -264,7 +200,6 @@ class DTMLMethod(RestrictedDTML,
file = file.read() file = file.read()
self.munge(file) self.munge(file)
self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message = "Saved changes." message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message) return self.manage_main(self, REQUEST, manage_tabs_message=message)
...@@ -299,7 +234,6 @@ class DTMLMethod(RestrictedDTML, ...@@ -299,7 +234,6 @@ class DTMLMethod(RestrictedDTML,
self._validateProxy(REQUEST, roles) self._validateProxy(REQUEST, roles)
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
self._proxy_roles = tuple(roles) self._proxy_roles = tuple(roles)
self.ZCacheable_invalidate()
if REQUEST: if REQUEST:
message = "Saved changes." message = "Saved changes."
return self.manage_proxyForm(self, REQUEST, return self.manage_proxyForm(self, REQUEST,
...@@ -327,7 +261,6 @@ class DTMLMethod(RestrictedDTML, ...@@ -327,7 +261,6 @@ class DTMLMethod(RestrictedDTML,
body = REQUEST.get('BODY', '') body = REQUEST.get('BODY', '')
self._validateProxy(REQUEST) self._validateProxy(REQUEST)
self.munge(body) self.munge(body)
self.ZCacheable_invalidate()
RESPONSE.setStatus(204) RESPONSE.setStatus(204)
return RESPONSE return RESPONSE
......
...@@ -97,7 +97,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -97,7 +97,6 @@ class File(Persistent, Implicit, PropertyManager,
implementedBy(PropertyManager), implementedBy(PropertyManager),
implementedBy(RoleManager), implementedBy(RoleManager),
implementedBy(Item_w__name__), implementedBy(Item_w__name__),
implementedBy(Cacheable),
IWriteLock, IWriteLock,
HTTPRangeSupport.HTTPRangeInterface) HTTPRangeSupport.HTTPRangeInterface)
...@@ -121,8 +120,7 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -121,8 +120,7 @@ class File(Persistent, Implicit, PropertyManager,
manage_options = ( manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) + ({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options + RoleManager.manage_options +
Item_w__name__.manage_options + Item_w__name__.manage_options
Cacheable.manage_options
) )
_properties = ( _properties = (
...@@ -382,13 +380,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -382,13 +380,6 @@ class File(Persistent, Implicit, PropertyManager,
""" """
if self._if_modified_since_request_handler(REQUEST, RESPONSE): if self._if_modified_since_request_handler(REQUEST, RESPONSE):
# we were able to handle this by returning a 304
# unfortunately, because the HTTP cache manager uses the cache
# API, and because 304 responses are required to carry the Expires
# header for HTTP/1.1, we need to call ZCacheable_set here.
# This is nonsensical for caches other than the HTTP cache manager
# unfortunately.
self.ZCacheable_set(None)
return '' return ''
if self.precondition and hasattr(self, str(self.precondition)): if self.precondition and hasattr(self, str(self.precondition)):
...@@ -410,17 +401,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -410,17 +401,6 @@ class File(Persistent, Implicit, PropertyManager,
RESPONSE.setHeader('Content-Length', self.size) RESPONSE.setHeader('Content-Length', self.size)
RESPONSE.setHeader('Accept-Ranges', 'bytes') RESPONSE.setHeader('Accept-Ranges', 'bytes')
if self.ZCacheable_isCachingEnabled():
result = self.ZCacheable_get(default=None)
if result is not None:
# We will always get None from RAMCacheManager and HTTP
# Accelerated Cache Manager but we will get
# something implementing the IStreamIterator interface
# from a "FileCacheManager"
return result
self.ZCacheable_set(None)
data = self.data data = self.data
if isinstance(data, str): if isinstance(data, str):
RESPONSE.setBase(None) RESPONSE.setBase(None)
...@@ -458,8 +438,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -458,8 +438,6 @@ class File(Persistent, Implicit, PropertyManager,
size = len(data) size = len(data)
self.size = size self.size = size
self.data = data self.data = data
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag() self.http__refreshEtag()
security.declareProtected(change_images_and_files, 'manage_edit') security.declareProtected(change_images_and_files, 'manage_edit')
...@@ -479,8 +457,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -479,8 +457,6 @@ class File(Persistent, Implicit, PropertyManager,
del self.precondition del self.precondition
if filedata is not None: if filedata is not None:
self.update_data(filedata, content_type, len(filedata)) self.update_data(filedata, content_type, len(filedata))
else:
self.ZCacheable_invalidate()
notify(ObjectModifiedEvent(self)) notify(ObjectModifiedEvent(self))
...@@ -641,18 +617,6 @@ class File(Persistent, Implicit, PropertyManager, ...@@ -641,18 +617,6 @@ class File(Persistent, Implicit, PropertyManager,
def manage_FTPget(self): def manage_FTPget(self):
"""Return body for ftp.""" """Return body for ftp."""
RESPONSE = self.REQUEST.RESPONSE RESPONSE = self.REQUEST.RESPONSE
if self.ZCacheable_isCachingEnabled():
result = self.ZCacheable_get(default=None)
if result is not None:
# We will always get None from RAMCacheManager but we will
# get something implementing the IStreamIterator interface
# from FileCacheManager.
# the content-length is required here by HTTPResponse,
# even though FTP doesn't use it.
RESPONSE.setHeader('Content-Length', self.size)
return result
data = self.data data = self.data
if isinstance(data, str): if isinstance(data, str):
RESPONSE.setBase(None) RESPONSE.setBase(None)
...@@ -809,8 +773,7 @@ class Image(File): ...@@ -809,8 +773,7 @@ class Image(File):
manage_options = ( manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) + ({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options + RoleManager.manage_options +
Item_w__name__.manage_options + Item_w__name__.manage_options
Cacheable.manage_options
) )
manage_editForm = DTMLFile('dtml/imageEdit', globals(), manage_editForm = DTMLFile('dtml/imageEdit', globals(),
...@@ -848,8 +811,6 @@ class Image(File): ...@@ -848,8 +811,6 @@ class Image(File):
if content_type is not None: if content_type is not None:
self.content_type = content_type self.content_type = content_type
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag() self.http__refreshEtag()
def __str__(self): def __str__(self):
......
...@@ -4,7 +4,4 @@ ...@@ -4,7 +4,4 @@
<five:deprecatedManageAddDelete <five:deprecatedManageAddDelete
class="OFS.userfolder.BasicUserFolder"/> class="OFS.userfolder.BasicUserFolder"/>
<five:deprecatedManageAddDelete
class="OFS.Cache.CacheManager"/>
</configure> </configure>
<p class="form-text">
Names from the DTML namespace to use as cache keys:
</p>
<textarea name="keys:lines" cols="40" rows="5"><dtml-in
getCacheNamespaceKeys>&dtml-sequence-item;
</dtml-in></textarea>
<br>
<div class="form-element">
<input class="form-element" type="submit"
name="setCacheNamespaceKeys:method" value="Save Changes">
</div>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="&dtml-absolute_url;" method="POST">
<div class="form-element">
<span class="form-label">
Cache this object using:
</span>
<select name="manager_id">
<option value="">(None)</option>
<dtml-in ZCacheable_getManagerIds mapping>
<option value="&dtml-id;" <dtml-if
expr="id == ZCacheable_getManagerId()"
>selected="selected"</dtml-if>>&dtml-id;
<dtml-if title>(&dtml-title;)</dtml-if></option>
</dtml-in>
</select>
<br />
<input class="form-element" type="submit"
name="ZCacheable_setManagerId:method" value="Save Changes">
</div>
<dtml-if ZCacheable_getManagerURL>
<p class="form-text">
<a href="&dtml-ZCacheable_getManagerURL;/manage_main">Cache Settings</a>
</p>
<div class="form-element">
<input class="form-element" type="submit"
name="ZCacheable_invalidate:method" value="Invalidate">
</div>
</dtml-if>
<dtml-var ZCacheable_configHTML>
</form>
<dtml-var manage_page_footer>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="&dtml-URL1;" name="objectItems" method="POST">
<dtml-if show_results>
<dtml-if results>
<p class="form-help">
Select which objects should be cached using this cache manager. Only
those objects for which you have the "Change cache settings" permission
are shown.
</p>
<table width="100%" cellspacing="0" cellpadding="2" border="0">
<dtml-in results mapping sort=sortkey>
<dtml-if sequence-odd>
<tr class="row-normal">
<dtml-else>
<tr class="row-hilite">
</dtml-if>
<td align="left" valign="top">
<input type="checkbox" name="associate_&dtml-path;:int" value="1"<dtml-if
associated> checked="checked"</dtml-if>>
<input type="hidden" name="associate_&dtml-path;:int:default" value="0">
</td>
<td align="left" valign="top">
<div class="form-text">
<a href="../&dtml-path;/manage_main">&dtml-path;</a><dtml-if
title>(&dtml-title;)</dtml-if>
</div>
</td>
</tr>
</dtml-in>
<tr>
<td></td>
<td align="left" valign="top">
<div class="form-element">
<input type="submit" name="ZCacheManager_setAssociations:method"
value="Save Changes">
</div>
</td>
</tr>
</table>
</form>
<dtml-else>
<p class="form-text">
No objects matched your query.
</p>
</dtml-if>
<hr>
</dtml-if>
<form target="&dtml-URL1;" method="post">
<table cellspacing="0" cellpadding="2" border="0">
<tr>
<td align="left" valign="top">
<div class="form-label">
Locate cacheable objects:
</div>
</td>
<td align="left" valign="top">
<div class="form-text">
<input type="radio" name="require_assoc:int" value="0"
checked="checked"> All
<input type="radio" name="require_assoc:int" value="1">
Associated with this cache manager
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
Of the type(s):
</div>
</td>
<td align="left" valign="top">
<div class="form-element">
<select multiple="multiple" name="meta_types:list" size="5">
<option value="" selected>All</option>
<dtml-in all_meta_types mapping sort=name>
<option value="&dtml-name;">&dtml-name;</option>
</dtml-in>
</select>
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-text">
<input type="checkbox" name="subfolders:int" value="1" checked="checked">
<input type="hidden" name="subfolders:int" value="0">
Search subfolders
</div>
</td>
</tr>
<tr>
<td align="left" valign="top">
</td>
<td align="left" valign="top">
<div class="form-element">
<br>
<input type="submit" name="ZCacheManager_locate:method" value="Locate">
</div>
</td>
</tr>
</table>
</form>
<dtml-var manage_page_footer>
import unittest
from OFS.Cache import CacheManager
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from OFS.metaconfigure import setDeprecatedManageAddDelete
class DummyCacheManager(CacheManager, SimpleItem):
def __init__(self, id, *args, **kw):
self.id = id
setDeprecatedManageAddDelete(DummyCacheManager)
class CacheTests(unittest.TestCase):
def test_managersExist(self):
from OFS.Cache import managersExist
from OFS.DTMLMethod import DTMLMethod
root = Folder('root')
root._setObject('root_cache', DummyCacheManager('root_cache'))
root._setObject('child', Folder('child'))
root.child._setObject('child_cache', DummyCacheManager('child_cache'))
root.child._setObject('child_content', DTMLMethod('child_content'))
# To begin with, cache managers will be found correctly
# using managersExist
self.assertTrue(managersExist(root.child.child_content))
# Now we delete the cache in the child folder
root.child.manage_delObjects(['child_cache'])
# The parent_cache should still trigger managersExist
self.assertTrue(managersExist(root.child.child_content))
...@@ -11,8 +11,6 @@ from cStringIO import StringIO ...@@ -11,8 +11,6 @@ from cStringIO import StringIO
from Acquisition import aq_base from Acquisition import aq_base
from OFS.Application import Application from OFS.Application import Application
from OFS.SimpleItem import SimpleItem
from OFS.Cache import ZCM_MANAGERS
from OFS.Image import Pdata from OFS.Image import Pdata
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
...@@ -57,41 +55,6 @@ def aputrequest(file, content_type): ...@@ -57,41 +55,6 @@ def aputrequest(file, content_type):
return req return req
class DummyCache:
def __init__(self):
self.clear()
def ZCache_set(self, ob, data, view_name='', keywords=None,
mtime_func=None):
self.set = (ob, data)
def ZCache_get(self, ob, data, view_name='', keywords=None,
mtime_func=None):
self.get = ob
if self.si:
return self.si
def ZCache_invalidate(self, ob):
self.invalidated = ob
def clear(self):
self.set = None
self.get = None
self.invalidated = None
self.si = None
def setStreamIterator(self, si):
self.si = si
ADummyCache = DummyCache()
class DummyCacheManager(SimpleItem):
def ZCacheManager_getCache(self):
return ADummyCache
class EventCatcher(object): class EventCatcher(object):
def __init__(self): def __init__(self):
...@@ -139,13 +102,9 @@ class FileTests(unittest.TestCase): ...@@ -139,13 +102,9 @@ class FileTests(unittest.TestCase):
self.root = a self.root = a
responseOut = self.responseOut = StringIO() responseOut = self.responseOut = StringIO()
self.app = makerequest(self.root, stdout=responseOut) self.app = makerequest(self.root, stdout=responseOut)
self.app.dcm = DummyCacheManager()
factory = getattr(self.app, self.factory) factory = getattr(self.app, self.factory)
factory('file', factory('file',
file=self.data, content_type=self.content_type) file=self.data, content_type=self.content_type)
self.app.file.ZCacheable_setManagerId('dcm')
self.app.file.ZCacheable_setEnabled(enabled=1)
setattr(self.app, ZCM_MANAGERS, ('dcm',))
# Hack, we need a _p_mtime for the file, so we make sure that it # Hack, we need a _p_mtime for the file, so we make sure that it
# has one. # has one.
transaction.commit() transaction.commit()
...@@ -174,7 +133,6 @@ class FileTests(unittest.TestCase): ...@@ -174,7 +133,6 @@ class FileTests(unittest.TestCase):
del self.responseOut del self.responseOut
del self.root del self.root
del self.connection del self.connection
ADummyCache.clear()
self.eventCatcher.tearDown() self.eventCatcher.tearDown()
def testViewImageOrFile(self): def testViewImageOrFile(self):
...@@ -184,8 +142,6 @@ class FileTests(unittest.TestCase): ...@@ -184,8 +142,6 @@ class FileTests(unittest.TestCase):
self.file.update_data('foo') self.file.update_data('foo')
self.assertEqual(self.file.size, 3) self.assertEqual(self.file.size, 3)
self.assertEqual(self.file.data, 'foo') self.assertEqual(self.file.data, 'foo')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testReadData(self): def testReadData(self):
s = "a" * (2 << 16) s = "a" * (2 << 16)
...@@ -210,8 +166,6 @@ class FileTests(unittest.TestCase): ...@@ -210,8 +166,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain', filedata='ASD') self.file.manage_edit('foobar', 'text/plain', filedata='ASD')
self.assertEqual(self.file.title, 'foobar') self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain') self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
self.assertEquals(1, len(self.eventCatcher.modified)) self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file) self.assertTrue(self.eventCatcher.modified[0].object is self.file)
...@@ -219,7 +173,6 @@ class FileTests(unittest.TestCase): ...@@ -219,7 +173,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain') self.file.manage_edit('foobar', 'text/plain')
self.assertEqual(self.file.title, 'foobar') self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain') self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertEquals(1, len(self.eventCatcher.modified)) self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file) self.assertTrue(self.eventCatcher.modified[0].object is self.file)
...@@ -308,8 +261,6 @@ class ImageTests(FileTests): ...@@ -308,8 +261,6 @@ class ImageTests(FileTests):
self.assertEqual(self.file.data, self.data) self.assertEqual(self.file.data, self.data)
self.assertEqual(self.file.width, 16) self.assertEqual(self.file.width, 16)
self.assertEqual(self.file.height, 16) self.assertEqual(self.file.height, 16)
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testStr(self): def testStr(self):
self.assertEqual( self.assertEqual(
......
...@@ -88,7 +88,7 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable, ...@@ -88,7 +88,7 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
manage_options = ( manage_options = (
{'label': 'Edit', 'action': 'pt_editForm'}, {'label': 'Edit', 'action': 'pt_editForm'},
) + SimpleItem.manage_options + Cacheable.manage_options ) + SimpleItem.manage_options
_properties = ( _properties = (
{'id': 'title', 'type': 'ustring', 'mode': 'w'}, {'id': 'title', 'type': 'ustring', 'mode': 'w'},
...@@ -164,7 +164,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable, ...@@ -164,7 +164,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
if not is_unicode: if not is_unicode:
text = unicode(text, encoding) text = unicode(text, encoding)
self.ZCacheable_invalidate()
super(ZopePageTemplate, self).pt_edit(text, content_type) super(ZopePageTemplate, self).pt_edit(text, content_type)
pt_editForm = PageTemplateFile('www/ptEdit', globals(), pt_editForm = PageTemplateFile('www/ptEdit', globals(),
...@@ -204,11 +203,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable, ...@@ -204,11 +203,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
title = unicode(title, encoding) title = unicode(title, encoding)
self._setPropValue('title', title) 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') security.declareProtected(change_page_templates, 'pt_upload')
def pt_upload(self, REQUEST, file='', encoding='utf-8'): def pt_upload(self, REQUEST, file='', encoding='utf-8'):
"""Replace the document with the text in file.""" """Replace the document with the text in file."""
...@@ -248,14 +242,12 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable, ...@@ -248,14 +242,12 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
return c return c
def write(self, text): def write(self, text):
if not isinstance(text, unicode): if not isinstance(text, unicode):
text, encoding = convertToUnicode(text, text, encoding = convertToUnicode(text,
self.content_type, self.content_type,
preferred_encodings) preferred_encodings)
self.output_encoding = encoding self.output_encoding = encoding
self.ZCacheable_invalidate()
ZopePageTemplate.inheritedAttribute('write')(self, text) ZopePageTemplate.inheritedAttribute('write')(self, text)
def _exec(self, bound_names, args, kw): def _exec(self, bound_names, args, kw):
...@@ -273,25 +265,11 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable, ...@@ -273,25 +265,11 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
security = getSecurityManager() security = getSecurityManager()
bound_names['user'] = security.getUser() 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. # Execute the template in a new security context.
security.addContext(self) security.addContext(self)
try: try:
result = self.pt_render(extra_context=bound_names) 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 return result
finally: finally:
security.removeContext(self) security.removeContext(self)
......
...@@ -24,7 +24,6 @@ Products.MailHost = 3.0 ...@@ -24,7 +24,6 @@ Products.MailHost = 3.0
Products.PythonScripts = 4.0 Products.PythonScripts = 4.0
Products.Sessions = 4.0 Products.Sessions = 4.0
Products.SiteErrorLog = 4.0 Products.SiteErrorLog = 4.0
Products.StandardCacheManagers = 3.0
Products.TemporaryFolder = 4.0 Products.TemporaryFolder = 4.0
Products.ZCatalog = 4.0a2 Products.ZCatalog = 4.0a2
Products.ZCTextIndex = 4.0 Products.ZCTextIndex = 4.0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment