~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/Cheetah/CacheRegion.py

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# $Id: CacheRegion.py,v 1.3 2006/01/28 04:19:30 tavis_rudd Exp $
 
2
"""Cache holder classes for Cheetah:
 
3
 
 
4
Cache regions are defined using the #cache Cheetah directive. Each
 
5
cache region can be viewed as a dictionary (keyed by cacheRegionID)
 
6
handling at least one cache item (the default one). It's possible to add
 
7
cacheItems in a region by using the `varyBy` #cache directive parameter as
 
8
in the following example::
 
9
   #def getArticle
 
10
      this is the article content.
 
11
   #end def
 
12
 
 
13
   #cache varyBy=$getArticleID()
 
14
      $getArticle($getArticleID())
 
15
   #end cache
 
16
 
 
17
The code above will generate a CacheRegion and add new cacheItem for each value
 
18
of $getArticleID().
 
19
 
 
20
Meta-Data
 
21
================================================================================
 
22
Author: Tavis Rudd <tavis@damnsimple.com> and Philippe Normand <phil@base-art.net> 
 
23
Version: $Revision: 1.3 $
 
24
Start Date: 2005/06/20
 
25
Last Revision Date: $Date: 2006/01/28 04:19:30 $
 
26
"""
 
27
__author__ = "Tavis Rudd <tavis@damnsimple.com> and Philippe Normand <phil@base-art.net>"
 
28
__revision__ = "$Revision: 1.3 $"[11:-2]
 
29
 
 
30
import md5
 
31
from time import time as currentTime
 
32
from Cheetah.CacheStore import MemoryCacheStore
 
33
 
 
34
class CacheItem:
 
35
    """A CacheItem is a container storing:
 
36
 
 
37
        - cacheID (string)
 
38
        - refreshTime (timestamp or None) : last time the cache was refreshed
 
39
        - data (string) : the content of the cache
 
40
    """
 
41
    
 
42
    def __init__(self, cacheItemID, cacheStore):
 
43
        self._cacheItemID = cacheItemID
 
44
        self._cacheStore = cacheStore
 
45
        self._refreshTime = None
 
46
        self._expiryTime = 0
 
47
 
 
48
    def hasExpired(self):
 
49
        return (self._expiryTime and currentTime() > self._expiryTime)
 
50
    
 
51
    def setExpiryTime(self, time):
 
52
        self._expiryTime = time
 
53
 
 
54
    def getExpiryTime(self):
 
55
        return self._expiryTime
 
56
 
 
57
    def setData(self, data):
 
58
        self._refreshTime = currentTime()
 
59
        self._cacheStore.set(self._cacheItemID, data, self._expiryTime)
 
60
 
 
61
    def getRefreshTime(self):
 
62
        return self._refreshTime
 
63
 
 
64
    def getData(self):
 
65
        assert self._refreshTime
 
66
        return self._cacheStore.get(self._cacheItemID)
 
67
 
 
68
    def renderOutput(self):
 
69
        """Can be overridden to implement edge-caching"""
 
70
        return self.getData() or ""
 
71
 
 
72
    def clear(self):
 
73
        self._cacheStore.delete(self._cacheItemID)
 
74
        self._refreshTime = None
 
75
 
 
76
class _CacheDataStoreWrapper:
 
77
    def __init__(self, dataStore, keyPrefix):
 
78
        self._dataStore = dataStore
 
79
        self._keyPrefix = keyPrefix
 
80
        
 
81
    def get(self, key):
 
82
        return self._dataStore.get(self._keyPrefix+key)
 
83
 
 
84
    def delete(self, key):
 
85
        self._dataStore.delete(self._keyPrefix+key)
 
86
 
 
87
    def set(self, key, val, time=0):        
 
88
        self._dataStore.set(self._keyPrefix+key, val, time=time)
 
89
 
 
90
class CacheRegion:
 
91
    """ A `CacheRegion` stores some `CacheItem` instances.
 
92
 
 
93
    This implementation stores the data in the memory of the current process.
 
94
    If you need a more advanced data store, create a cacheStore class that works
 
95
    with Cheetah's CacheStore protocol and provide it as the cacheStore argument
 
96
    to __init__.  For example you could use
 
97
    Cheetah.CacheStore.MemcachedCacheStore, a wrapper around the Python
 
98
    memcached API (http://www.danga.com/memcached).
 
99
    """
 
100
    _cacheItemClass = CacheItem
 
101
    
 
102
    def __init__(self, regionID, templateCacheIdPrefix='', cacheStore=None):
 
103
        self._isNew = True
 
104
        self._regionID = regionID
 
105
        self._templateCacheIdPrefix = templateCacheIdPrefix
 
106
        if not cacheStore:
 
107
            cacheStore = MemoryCacheStore()
 
108
        self._cacheStore = cacheStore
 
109
        self._wrappedCacheDataStore = _CacheDataStoreWrapper(
 
110
            cacheStore, keyPrefix=templateCacheIdPrefix+':'+regionID+':')
 
111
        self._cacheItems = {}
 
112
 
 
113
    def isNew(self):
 
114
        return self._isNew
 
115
        
 
116
    def clear(self):
 
117
        " drop all the caches stored in this cache region "
 
118
        for cacheItemId in self._cacheItems.keys():
 
119
            cacheItem = self._cacheItems[cacheItemId]
 
120
            cacheItem.clear()
 
121
            del self._cacheItems[cacheItemId]
 
122
        
 
123
    def getCacheItem(self, cacheItemID):
 
124
        """ Lazy access to a cacheItem
 
125
 
 
126
            Try to find a cache in the stored caches. If it doesn't
 
127
            exist, it's created.
 
128
            
 
129
            Returns a `CacheItem` instance.
 
130
        """
 
131
        cacheItemID = md5.new(str(cacheItemID)).hexdigest()
 
132
        
 
133
        if not self._cacheItems.has_key(cacheItemID):
 
134
            cacheItem = self._cacheItemClass(
 
135
                cacheItemID=cacheItemID, cacheStore=self._wrappedCacheDataStore)
 
136
            self._cacheItems[cacheItemID] = cacheItem
 
137
            self._isNew = False
 
138
        return self._cacheItems[cacheItemID]