1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 Contains basic caching classes.
19 """
20
21 import os
22 import suds
23 from tempfile import gettempdir as tmp
24 from suds.transport import *
25 from suds.sax.parser import Parser
26 from suds.sax.element import Element
27 from datetime import datetime as dt
28 from datetime import timedelta
29 from cStringIO import StringIO
30 from logging import getLogger
31 try:
32 import cPickle as pickle
33 except:
34 import pickle
35
36 log = getLogger(__name__)
37
38
40 """
41 An object object cache.
42 """
43
45 """
46 Get a object from the cache by ID.
47 @param id: The object ID.
48 @type id: str
49 @return: The object, else None
50 @rtype: any
51 """
52 raise Exception('not-implemented')
53
55 """
56 Get a object from the cache by ID.
57 @param id: The object ID.
58 @type id: str
59 @return: The object, else None
60 @rtype: any
61 """
62 raise Exception('not-implemented')
63
64 - def put(self, id, object):
65 """
66 Put a object into the cache.
67 @param id: The object ID.
68 @type id: str
69 @param object: The object to add.
70 @type object: any
71 """
72 raise Exception('not-implemented')
73
74 - def putf(self, id, fp):
75 """
76 Write a fp into the cache.
77 @param id: The object ID.
78 @type id: str
79 @param fp: File pointer.
80 @type fp: file-like object.
81 """
82 raise Exception('not-implemented')
83
85 """
86 Purge a object from the cache by id.
87 @param id: A object ID.
88 @type id: str
89 """
90 raise Exception('not-implemented')
91
93 """
94 Clear all objects from the cache.
95 """
96 raise Exception('not-implemented')
97
98
100 """
101 The passthru object cache.
102 """
103
106
107 - def getf(self, id):
109
110 - def put(self, id, object):
112
113 - def putf(self, id, fp):
115
116
118 """
119 A file-based URL cache.
120 @cvar fnprefix: The file name prefix.
121 @type fnsuffix: str
122 @ivar duration: The cached file duration which defines how
123 long the file will be cached.
124 @type duration: (unit, value)
125 @ivar location: The directory for the cached files.
126 @type location: str
127 """
128 fnprefix = 'suds'
129 units = ('months', 'weeks', 'days', 'hours', 'minutes', 'seconds')
130
131 - def __init__(self, location=None, **duration):
132 """
133 @param location: The directory for the cached files.
134 @type location: str
135 @param duration: The cached file duration which defines how
136 long the file will be cached. A duration=0 means forever.
137 The duration may be: (months|weeks|days|hours|minutes|seconds).
138 @type duration: {unit:value}
139 """
140 if location is None:
141 location = os.path.join(tmp(), 'suds')
142 self.location = location
143 self.duration = (None, 0)
144 self.setduration(**duration)
145 self.checkversion()
146
148 """
149 Get the file name suffix
150 @return: The suffix
151 @rtype: str
152 """
153 return 'gcf'
154
156 """
157 Set the caching duration which defines how long the
158 file will be cached.
159 @param duration: The cached file duration which defines how
160 long the file will be cached. A duration=0 means forever.
161 The duration may be: (months|weeks|days|hours|minutes|seconds).
162 @type duration: {unit:value}
163 """
164 if len(duration) == 1:
165 arg = duration.items()[0]
166 if not arg[0] in self.units:
167 raise Exception('must be: %s' % str(self.units))
168 self.duration = arg
169 return self
170
172 """
173 Set the location (directory) for the cached files.
174 @param location: The directory for the cached files.
175 @type location: str
176 """
177 self.location = location
178
180 """
181 Make the I{location} directory if it doesn't already exits.
182 """
183 try:
184 if not os.path.isdir(self.location):
185 os.makedirs(self.location)
186 except:
187 log.debug(self.location, exc_info=1)
188 return self
189
190 - def put(self, id, bfr):
191 try:
192 fn = self.__fn(id)
193 f = self.open(fn, 'w')
194 f.write(bfr)
195 f.close()
196 return bfr
197 except:
198 log.debug(id, exc_info=1)
199 return bfr
200
201 - def putf(self, id, fp):
202 try:
203 fn = self.__fn(id)
204 f = self.open(fn, 'w')
205 f.write(fp.read())
206 fp.close()
207 f.close()
208 return open(fn)
209 except:
210 log.debug(id, exc_info=1)
211 return fp
212
214 try:
215 f = self.getf(id)
216 bfr = f.read()
217 f.close()
218 return bfr
219 except:
220 pass
221
222 - def getf(self, id):
223 try:
224 fn = self.__fn(id)
225 self.validate(fn)
226 return self.open(fn)
227 except:
228 pass
229
231 """
232 Validate that the file has not expired based on the I{duration}.
233 @param fn: The file name.
234 @type fn: str
235 """
236 if self.duration[1] < 1:
237 return
238 created = dt.fromtimestamp(os.path.getctime(fn))
239 d = { self.duration[0]:self.duration[1] }
240 expired = created+timedelta(**d)
241 if expired < dt.now():
242 log.debug('%s expired, deleted', fn)
243 os.remove(fn)
244
246 for fn in os.listdir(self.location):
247 path = os.path.join(self.location, fn)
248 if os.path.isdir(path):
249 continue
250 if fn.startswith(self.fnprefix):
251 os.remove(path)
252 log.debug('deleted: %s', path)
253
255 fn = self.__fn(id)
256 try:
257 os.remove(fn)
258 except:
259 pass
260
261 - def open(self, fn, *args):
262 """
263 Open the cache file making sure the directory is created.
264 """
265 self.mktmp()
266 return open(fn, *args)
267
269 path = os.path.join(self.location, 'version')
270 try:
271
272 f = self.open(path)
273 version = f.read()
274 f.close()
275 if version != suds.__version__:
276 raise Exception()
277 except:
278 self.clear()
279 f = self.open(path, 'w')
280 f.write(suds.__version__)
281 f.close()
282
283 - def __fn(self, id):
284 name = id
285 suffix = self.fnsuffix()
286 fn = '%s-%s.%s' % (self.fnprefix, name, suffix)
287 return os.path.join(self.location, fn)
288
289
291 """
292 Provides xml document caching.
293 """
294
297
307
308 - def put(self, id, object):
312
313
315 """
316 Provides pickled object caching.
317 @cvar protocol: The pickling protocol.
318 @type protocol: int
319 """
320 protocol = 2
321
324
326 try:
327 fp = FileCache.getf(self, id)
328 if fp is None:
329 return None
330 else:
331 return pickle.load(fp)
332 except:
333 FileCache.purge(self, id)
334
335 - def put(self, id, object):
339