This repository has been archived by the owner on Oct 12, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Cheetah
155 lines (130 loc) · 5.58 KB
/
Cheetah
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
= How to use powerful Cheetah cache mechanism with CherryPy? =
Cheetah Template uses quite powerful cache mechanism. I have just improved its features with 'varyBy' keyword argument that will allow a separate cache instances to be created for a variety of conditions, such as different query string parameters or browser types.
Look at the example. First lets upgrade two functions from Compiler.py file (found in Lib/site-libs/Cheetah/src folder) to the following code:
{{{
#!python
def startCacheRegion(self, cacheInfo, lineCol):
"""
Added params: varyBy, debug.
Author: Jarosław Zabiełło (http://zabiello.com)
Version: 2004-11-28
"""
ID = self.nextCacheID()
interval = cacheInfo.get('interval',None)
test = cacheInfo.get('test',None)
self.__CacheRegionVaryBy = cacheInfo.get('varyBy',repr(ID))
self.__CacheRegionDebug = cacheInfo.get('debug', False)
self._cacheRegionOpen = True # attrib of current methodCompiler
self.addChunk('## START CACHE REGION: at line, col ' + str(lineCol) + ' in the source.')
self.addChunk('RECACHE = True')
self.addChunk('import md5')
self.addChunk('self._varyByHash = md5.new(str(%s)).hexdigest()' % self.__CacheRegionVaryBy)
self.addChunk('if self._varyByHash not in self._cacheData:')
self.indent()
self.addChunk("self._cacheData[self._varyByHash] = {'output':None, 'refreshTime':None}")
if 'id' in cacheInfo:
self.addChunk("self._cacheIndex['%s']= self._varyByHash" % cacheInfo['id'])
if not (interval or test):
self.addChunk('pass')
if interval:
setRefreshTime = "self._cacheData[self._varyByHash]['refreshTime'] = currentTime() + %s" % interval
self.addChunk(setRefreshTime)
self.dedent()
self.addChunk("elif currentTime() > self._cacheData[self._varyByHash]['refreshTime']:")
self.indent()
self.addChunk(setRefreshTime)
self.addMethDocString('This cache will be refreshed every %s seconds.' % interval)
if test:
self.dedent()
self.addChunk('elif ' + test + ':')
self.indent()
self.addChunk('RECACHE = True')
self.dedent()
self.addChunk('else:')
self.indent()
self.addChunk('RECACHE = False')
self.dedent()
self.addChunk('if RECACHE:')
self.indent()
self.addChunk('orig_trans = trans')
self.addChunk('trans = cacheCollector = DummyTransaction()')
self.addChunk('write = cacheCollector.response().write')
def endCacheRegion(self):
self._cacheRegionOpen = False
self.addChunk('trans = orig_trans')
self.addChunk('write = trans.response().write')
self.addChunk("self._cacheData[self._varyByHash]['output'] = cacheCollector.response().getvalue()")
self.addChunk('del cacheCollector')
self.dedent()
self.addWriteChunk("self._cacheData[self._varyByHash]['output']")
if self.__CacheRegionDebug:
self.addWriteChunk("'<hr />%s' % self._cacheData")
self.addChunk('## END CACHE REGION')
self.addChunk('')
}}}
OK. Now, let's check how it works. First, create the following test files.
File: !TestTemplate.html
{{{
#!python
#import cherrypy
#import time
Hello $username!
#set $_varyBy=$cherrypy.request.params.get('x')
#set $_test=$cherrypy.request.params.get('refresh')
#cache id='test', test=$_test, timer='10s', varyBy=$_varyBy, debug=True
$time.strftime('%H:%M:%S', time.localtime())
#end cache
}}}
File: Test.py
{{{
#!python
from Cheetah.Template import Template
import cherrypy
#import compiled TestTemplate:
from TestTemplate import TestTemplate
class TestCheetah(object):
def __init__(self):
"""
For threadPool=1 or for forks mode you can define instance
of Cheetah here, in constructor.
For threadPool > 1 it should be defined in engine.on_start_thread
method because it have to be executed only ONCE and you must aware
of threads conflict. on_start_thread is a good place. If you create
instance of TestTemplate in the place where it will be executed
for every browser request, Cheetah cache wil NOT work!
"""
self._tmpl = TestTemplate()
self._tmpl.username = "John Brown"
def index(self, **kwargs):
return self._tmpl.respond()
index.exposed = True
cherrypy.quickstart(TestCheetah(), conf='test.conf')
}}}
File test.conf:
{{{
[/]
server.socket_port = 8080
server.thread_pool = 1
}}}
Of course, !TestTemplate.html should be compiled first. You can do do it and execute !CherryPy with the following script:
{{{
python cheetah-compile.py TestTemplate.html --iext html
python Test.py
}}}
Execute, check results and have a fun! :)
{{{
#!html
<h2 class='compatibility'>Older versions</h2>
}}}
|| || replace this || with this ||
||2.2||cherrypy.quickstart(TestCheetah(), conf='test.conf')||cherrypy.config.update(configFile = 'test.conf')[[br]]cherrypy.tree.mount(TestCheetah())[[br]]cpg.server.start()||
||2.1||on_start_thread_list||onStartThreadList||
||2.0||onStartThreadList||_cpInitThread()||
|| ||import cherrypy||from cherrypy import cpg as cherrypy||
|| ||cherrypy.quickstart(TestCheetah(), conf='test.conf')||cpg.root = TestCheetah()[[br]]cpg.server.start(configFile = 'test.conf')||
test.conf for 2.0:
{{{
[server]
socketPort = 8080
threadPool = 1
}}}