Commit dbb476e6 authored by Hanno Schlichting's avatar Hanno Schlichting

Remove ZCacheable logic and StandardCacheManagers dependency.

parent dabb9766
......@@ -30,6 +30,8 @@ Features Added
Restructuring
+++++++++++++
- Remove ZCacheable logic and StandardCacheManagers dependency.
- Stop mixing in `Five.bbb.AcquisitionBBB` into browser components.
- Integrate `five.pt` code directly into `Products.PageTemplates`.
......@@ -309,5 +311,4 @@ Restructuring
``Products.SiteErrorLog``
``Products.StandardCacheManagers``
``Products.ZCatalog``
``Products.ZCTextIndex``
``Record``
......@@ -72,7 +72,6 @@ eggs =
Products.PythonScripts
Products.Sessions
Products.SiteErrorLog
Products.StandardCacheManagers
Products.TemporaryFolder
Products.ZCatalog
Record
......
......@@ -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.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.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.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
......
......@@ -14,20 +14,10 @@
"""
from logging import getLogger
import sys
import time
from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import view_management_screens
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__'
......@@ -37,18 +27,16 @@ LOG = getLogger('Cache')
def isCacheable(ob):
return getattr(aq_base(ob), '_isCacheable', 0)
return False
def managersExist(ob):
# Returns 1 if any CacheManagers exist in the context of ob.
if aq_get(ob, ZCM_MANAGERS, None, 1):
return 1
return 0
return False
def filterCacheTab(ob):
return managersExist(ob)
return False
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
in the list of cache managers.
'''
if (hasattr(aq_base(container), ZCM_MANAGERS) and
name in getattr(container, ZCM_MANAGERS)):
return 1
return 0
return False
def getVerifiedManagerIds(container):
'''
Gets the list of cache managers in a container, verifying each one.
'''
ids = getattr(container, ZCM_MANAGERS, ())
rval = []
for id in ids:
if getattr(getattr(container, id, None), '_isCacheManager', 0):
rval.append(id)
return tuple(rval)
return ()
# Anytime a CacheManager is added or removed, all _v_ZCacheable_cache
......@@ -81,61 +61,31 @@ def getVerifiedManagerIds(container):
manager_timestamp = 0
class Cacheable:
class Cacheable(object):
'''Mix-in for cacheable objects.
'''
manage_options = (
{'label': 'Cache', 'action': 'ZCacheable_manage',
'filter': filterCacheTab},
)
manage_options = ()
security = ClassSecurityInfo()
security.setPermissionDefault(ChangeCacheSettingsPermission, ('Manager',))
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_manage')
ZCacheable_manage = DTMLFile('dtml/cacheable', globals())
_v_ZCacheable_cache = None
_v_ZCacheable_manager_timestamp = 0
__manager_id = None
__enabled = 1
_isCacheable = 1
__enabled = False
_isCacheable = False
security.declarePrivate('ZCacheable_getManager')
def ZCacheable_getManager(self):
'''Returns the currently associated cache manager.'''
manager_id = self.__manager_id
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
return None
security.declarePrivate('ZCacheable_getCache')
def ZCacheable_getCache(self):
'''Gets the cache associated with this object.
'''
if self.__manager_id is 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
return None
security.declarePrivate('ZCacheable_isCachingEnabled')
def ZCacheable_isCachingEnabled(self):
......@@ -143,7 +93,7 @@ class Cacheable:
Returns true only if associated with a cache manager and
caching of this method is enabled.
'''
return self.__enabled and self.ZCacheable_getCache()
return False
security.declarePrivate('ZCacheable_getObAndView')
def ZCacheable_getObAndView(self, view_name):
......@@ -157,16 +107,6 @@ class Cacheable:
conditions specified by keywords. If the value is
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
security.declarePrivate('ZCacheable_set')
......@@ -175,14 +115,7 @@ class Cacheable:
'''Cacheable views should call this method after generating
cacheable results. The data argument can be of any Python type.
'''
c = self.ZCacheable_getCache()
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')
pass
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_invalidate')
......@@ -191,60 +124,23 @@ class Cacheable:
cache entries that apply to the view_name to be removed.
Returns a status message.
'''
c = self.ZCacheable_getCache()
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
pass
security.declarePrivate('ZCacheable_getModTime')
def ZCacheable_getModTime(self, mtime_func=None):
'''Returns the highest of the last mod times.'''
# Based on:
# 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
return 0
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_getManagerId')
def ZCacheable_getManagerId(self):
'''Returns the id of the current ZCacheManager.'''
return self.__manager_id
return None
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_getManagerURL')
def ZCacheable_getManagerURL(self):
'''Returns the URL of the current ZCacheManager.'''
manager = self.ZCacheable_getManager()
if manager is not None:
return manager.absolute_url()
return None
security.declareProtected(ViewManagementScreensPermission,
......@@ -252,120 +148,31 @@ class Cacheable:
def ZCacheable_getManagerIds(self):
'''Returns a list of mappings containing the id and title
of the available ZCacheManagers.'''
rval = []
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)
return ()
security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheable_setManagerId')
def ZCacheable_setManagerId(self, manager_id, REQUEST=None):
'''Changes the manager_id for this object.'''
self.ZCacheable_invalidate()
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.')
pass
security.declareProtected(ViewManagementScreensPermission,
'ZCacheable_enabled')
def ZCacheable_enabled(self):
'''Returns true if caching is enabled for this object
or method.'''
return self.__enabled
return False
security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheable_setEnabled')
def ZCacheable_setEnabled(self, enabled=0, REQUEST=None):
'''Changes the enabled flag.'''
self.__enabled = enabled and 1 or 0
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 ''
pass
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:
'''
A base class (and interface description) for caches.
......@@ -414,37 +221,15 @@ class CacheManager:
_isCacheManager = 1
manage_options = (
{'label': 'Associate', 'action': 'ZCacheManager_associate'},
)
manage_options = ()
def manage_afterAdd(self, item, container):
# Adds self to the list of cache managers in the container.
if aq_base(self) is aq_base(item):
ids = getVerifiedManagerIds(container)
id = self.getId()
if id not in ids:
setattr(container, ZCM_MANAGERS, ids + (id,))
global manager_timestamp
manager_timestamp = time.time()
pass
def manage_beforeDelete(self, item, container):
# Removes self from the list of cache managers.
if aq_base(self) is aq_base(item):
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())
pass
security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheManager_locate')
......@@ -452,20 +237,7 @@ class CacheManager:
meta_types=[], REQUEST=None):
'''Locates cacheable objects.
'''
ob = aq_parent(aq_inner(self))
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
return []
security.declareProtected(ChangeCacheSettingsPermission,
'ZCacheManager_setAssociations')
......@@ -473,36 +245,6 @@ class CacheManager:
'''Associates and un-associates cacheable objects with this
cache manager.
'''
addcount = 0
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)
)
pass
InitializeClass(CacheManager)
......@@ -59,7 +59,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
file = file.read()
self.munge(file)
self.ZCacheable_invalidate()
if REQUEST:
message = "Content uploaded."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -69,12 +68,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
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)
kw['document_id'] = self.getId()
kw['document_title'] = self.title
......@@ -94,15 +87,11 @@ class DTMLDocument(PropertyManager, DTMLMethod):
result = r
else:
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
r = HTML.__call__(self, (client, bself), REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r
finally:
......@@ -116,8 +105,6 @@ class DTMLDocument(PropertyManager, DTMLMethod):
c, e = guess_content_type(self.__name__, r)
RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
......
......@@ -36,7 +36,6 @@ from OFS.role import RoleManager
from OFS.SimpleItem import Item_w__name__
from zExceptions import Forbidden, ResourceLockedError
from zExceptions.TracebackSupplement import PathTracebackSupplement
from ZPublisher.Iterators import IStreamIterator
from zope.contenttype import guess_content_type
if sys.version_info >= (3, ):
......@@ -49,14 +48,13 @@ class DTMLMethod(RestrictedDTML,
HTML,
Implicit,
RoleManager,
Item_w__name__,
Cacheable):
Cacheable,
Item_w__name__):
""" DocumentTemplate.HTML objects that act as methods of their containers.
"""
meta_type = 'DTML Method'
_proxy_roles = ()
index_html = None # Prevent accidental acquisition
_cache_namespace_keys = ()
security = ClassSecurityInfo()
security.declareObjectProtected(View)
......@@ -74,8 +72,7 @@ class DTMLMethod(RestrictedDTML,
{'label': 'Proxy', 'action': 'manage_proxyForm'},
) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
# More reasonable default for content-type for http HEAD requests.
......@@ -91,27 +88,6 @@ class DTMLMethod(RestrictedDTML,
o If supplied, use the REQUEST mapping, Response, and key word
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)
kw['document_id'] = self.getId()
kw['document_title'] = self.title
......@@ -132,14 +108,10 @@ class DTMLMethod(RestrictedDTML,
result = r
else:
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
r = HTML.__call__(self, client, REQUEST, **kw)
if RESPONSE is None or not isinstance(r, str):
if not self._cache_namespace_keys:
self.ZCacheable_set(r)
return r
finally:
......@@ -155,59 +127,24 @@ class DTMLMethod(RestrictedDTML,
c, e = guess_content_type(self.getId(), r)
RESPONSE.setHeader('Content-Type', c)
result = decapitate(r, RESPONSE)
if not self._cache_namespace_keys:
self.ZCacheable_set(result)
return result
def validate(self, inst, parent, name, value, md=None):
return getSecurityManager().validate(inst, parent, name, value)
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
def ZDocumentTemplate_afterRender(self, md, result):
# Tries to set a cache value.
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())
pass
security.declareProtected(change_dtml_methods, 'getCacheNamespaceKeys')
def getCacheNamespaceKeys(self):
# Return the cacheNamespaceKeys.
return self._cache_namespace_keys
return ()
security.declareProtected(change_dtml_methods, 'setCacheNamespaceKeys')
def setCacheNamespaceKeys(self, keys, REQUEST=None):
# Set the list of names looked up to provide a cache key.
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)
pass
security.declareProtected(View, 'get_size')
def get_size(self):
......@@ -245,7 +182,6 @@ class DTMLMethod(RestrictedDTML,
if not isinstance(data, basestring):
data = data.read()
self.munge(data)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -264,7 +200,6 @@ class DTMLMethod(RestrictedDTML,
file = file.read()
self.munge(file)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_main(self, REQUEST, manage_tabs_message=message)
......@@ -299,7 +234,6 @@ class DTMLMethod(RestrictedDTML,
self._validateProxy(REQUEST, roles)
self._validateProxy(REQUEST)
self._proxy_roles = tuple(roles)
self.ZCacheable_invalidate()
if REQUEST:
message = "Saved changes."
return self.manage_proxyForm(self, REQUEST,
......@@ -327,7 +261,6 @@ class DTMLMethod(RestrictedDTML,
body = REQUEST.get('BODY', '')
self._validateProxy(REQUEST)
self.munge(body)
self.ZCacheable_invalidate()
RESPONSE.setStatus(204)
return RESPONSE
......
......@@ -97,7 +97,6 @@ class File(Persistent, Implicit, PropertyManager,
implementedBy(PropertyManager),
implementedBy(RoleManager),
implementedBy(Item_w__name__),
implementedBy(Cacheable),
IWriteLock,
HTTPRangeSupport.HTTPRangeInterface)
......@@ -121,8 +120,7 @@ class File(Persistent, Implicit, PropertyManager,
manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
_properties = (
......@@ -382,13 +380,6 @@ class File(Persistent, Implicit, PropertyManager,
"""
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 ''
if self.precondition and hasattr(self, str(self.precondition)):
......@@ -410,17 +401,6 @@ class File(Persistent, Implicit, PropertyManager,
RESPONSE.setHeader('Content-Length', self.size)
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
if isinstance(data, str):
RESPONSE.setBase(None)
......@@ -458,8 +438,6 @@ class File(Persistent, Implicit, PropertyManager,
size = len(data)
self.size = size
self.data = data
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
security.declareProtected(change_images_and_files, 'manage_edit')
......@@ -479,8 +457,6 @@ class File(Persistent, Implicit, PropertyManager,
del self.precondition
if filedata is not None:
self.update_data(filedata, content_type, len(filedata))
else:
self.ZCacheable_invalidate()
notify(ObjectModifiedEvent(self))
......@@ -641,18 +617,6 @@ class File(Persistent, Implicit, PropertyManager,
def manage_FTPget(self):
"""Return body for ftp."""
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
if isinstance(data, str):
RESPONSE.setBase(None)
......@@ -809,8 +773,7 @@ class Image(File):
manage_options = (
({'label': 'Edit', 'action': 'manage_main'}, ) +
RoleManager.manage_options +
Item_w__name__.manage_options +
Cacheable.manage_options
Item_w__name__.manage_options
)
manage_editForm = DTMLFile('dtml/imageEdit', globals(),
......@@ -848,8 +811,6 @@ class Image(File):
if content_type is not None:
self.content_type = content_type
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
def __str__(self):
......
......@@ -4,7 +4,4 @@
<five:deprecatedManageAddDelete
class="OFS.userfolder.BasicUserFolder"/>
<five:deprecatedManageAddDelete
class="OFS.Cache.CacheManager"/>
</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
from Acquisition import aq_base
from OFS.Application import Application
from OFS.SimpleItem import SimpleItem
from OFS.Cache import ZCM_MANAGERS
from OFS.Image import Pdata
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
......@@ -57,41 +55,6 @@ def aputrequest(file, content_type):
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):
def __init__(self):
......@@ -139,13 +102,9 @@ class FileTests(unittest.TestCase):
self.root = a
responseOut = self.responseOut = StringIO()
self.app = makerequest(self.root, stdout=responseOut)
self.app.dcm = DummyCacheManager()
factory = getattr(self.app, self.factory)
factory('file',
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
# has one.
transaction.commit()
......@@ -174,7 +133,6 @@ class FileTests(unittest.TestCase):
del self.responseOut
del self.root
del self.connection
ADummyCache.clear()
self.eventCatcher.tearDown()
def testViewImageOrFile(self):
......@@ -184,8 +142,6 @@ class FileTests(unittest.TestCase):
self.file.update_data('foo')
self.assertEqual(self.file.size, 3)
self.assertEqual(self.file.data, 'foo')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testReadData(self):
s = "a" * (2 << 16)
......@@ -210,8 +166,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain', filedata='ASD')
self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file)
......@@ -219,7 +173,6 @@ class FileTests(unittest.TestCase):
self.file.manage_edit('foobar', 'text/plain')
self.assertEqual(self.file.title, 'foobar')
self.assertEqual(self.file.content_type, 'text/plain')
self.assertTrue(ADummyCache.invalidated)
self.assertEquals(1, len(self.eventCatcher.modified))
self.assertTrue(self.eventCatcher.modified[0].object is self.file)
......@@ -308,8 +261,6 @@ class ImageTests(FileTests):
self.assertEqual(self.file.data, self.data)
self.assertEqual(self.file.width, 16)
self.assertEqual(self.file.height, 16)
self.assertTrue(ADummyCache.invalidated)
self.assertTrue(ADummyCache.set)
def testStr(self):
self.assertEqual(
......
......@@ -88,7 +88,7 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
manage_options = (
{'label': 'Edit', 'action': 'pt_editForm'},
) + SimpleItem.manage_options + Cacheable.manage_options
) + SimpleItem.manage_options
_properties = (
{'id': 'title', 'type': 'ustring', 'mode': 'w'},
......@@ -164,7 +164,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
if not is_unicode:
text = unicode(text, encoding)
self.ZCacheable_invalidate()
super(ZopePageTemplate, self).pt_edit(text, content_type)
pt_editForm = PageTemplateFile('www/ptEdit', globals(),
......@@ -204,11 +203,6 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
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."""
......@@ -248,14 +242,12 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
return c
def write(self, text):
if not isinstance(text, unicode):
text, encoding = convertToUnicode(text,
self.content_type,
preferred_encodings)
self.output_encoding = encoding
self.ZCacheable_invalidate()
ZopePageTemplate.inheritedAttribute('write')(self, text)
def _exec(self, bound_names, args, kw):
......@@ -273,25 +265,11 @@ class ZopePageTemplate(Script, PageTemplate, Cacheable,
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:
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)
......
......@@ -24,7 +24,6 @@ Products.MailHost = 3.0
Products.PythonScripts = 4.0
Products.Sessions = 4.0
Products.SiteErrorLog = 4.0
Products.StandardCacheManagers = 3.0
Products.TemporaryFolder = 4.0
Products.ZCatalog = 4.0a2
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