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 Exception:
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 Exception:
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 Exception:
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 Exception:
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 Exception:
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 Exception:
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 if os.path.isdir(fn):
248 continue
249 if fn.startswith(self.fnprefix):
250 log.debug('deleted: %s', fn)
251 os.remove(os.path.join(self.location, fn))
252
254 fn = self.__fn(id)
255 try:
256 os.remove(fn)
257 except Exception:
258 pass
259
260 - def open(self, fn, *args):
261 """
262 Open the cache file making sure the directory is created.
263 """
264 self.mktmp()
265 return open(fn, *args)
266
268 path = os.path.join(self.location, 'version')
269 try:
270
271 f = self.open(path)
272 version = f.read()
273 f.close()
274 if version != suds.__version__:
275 raise Exception()
276 except Exception:
277 self.clear()
278 f = self.open(path, 'w')
279 f.write(suds.__version__)
280 f.close()
281
282 - def __fn(self, id):
287
288
290 """
291 Provides xml document caching.
292 """
293
296
306
307 - def put(self, id, object):
311
312
314 """
315 Provides pickled object caching.
316 @cvar protocol: The pickling protocol.
317 @type protocol: int
318 """
319 protocol = 2
320
323
325 try:
326 fp = FileCache.getf(self, id)
327 if fp is None:
328 return None
329 else:
330 return pickle.load(fp)
331 except Exception:
332 FileCache.purge(self, id)
333
334 - def put(self, id, object):
338