Package suds :: Module cache
[hide private]
[frames] | no frames]

Source Code for Module suds.cache

  1  # This program is free software; you can redistribute it and/or modify 
  2  # it under the terms of the (LGPL) GNU Lesser General Public License as 
  3  # published by the Free Software Foundation; either version 3 of the  
  4  # License, or (at your option) any later version. 
  5  # 
  6  # This program is distributed in the hope that it will be useful, 
  7  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  8  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  9  # GNU Library Lesser General Public License for more details at 
 10  # ( http://www.gnu.org/licenses/lgpl.html ). 
 11  # 
 12  # You should have received a copy of the GNU Lesser General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # written by: Jeff Ortel ( jortel@redhat.com ) 
 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   
39 -class Cache:
40 """ 41 An object object cache. 42 """ 43
44 - def get(self, id):
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
54 - def getf(self, id):
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
84 - def purge(self, id):
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
92 - def clear(self):
93 """ 94 Clear all objects from the cache. 95 """ 96 raise Exception('not-implemented')
97 98
99 -class NoCache(Cache):
100 """ 101 The passthru object cache. 102 """ 103
104 - def get(self, id):
105 return None
106
107 - def getf(self, id):
108 return None
109
110 - def put(self, id, object):
111 pass
112
113 - def putf(self, id, fp):
114 pass
115 116
117 -class FileCache(Cache):
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
147 - def fnsuffix(self):
148 """ 149 Get the file name suffix 150 @return: The suffix 151 @rtype: str 152 """ 153 return 'gcf'
154
155 - def setduration(self, **duration):
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
171 - def setlocation(self, location):
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
179 - def mktmp(self):
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
213 - def get(self, id):
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
230 - def validate(self, fn):
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
245 - def clear(self):
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
253 - def purge(self, id):
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
267 - def checkversion(self):
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):
283 name = id 284 suffix = self.fnsuffix() 285 fn = '%s-%s.%s' % (self.fnprefix, name, suffix) 286 return os.path.join(self.location, fn)
287 288
289 -class DocumentCache(FileCache):
290 """ 291 Provides xml document caching. 292 """ 293
294 - def fnsuffix(self):
295 return 'xml'
296
297 - def get(self, id):
298 try: 299 fp = FileCache.getf(self, id) 300 if fp is None: 301 return None 302 p = Parser() 303 return p.parse(fp) 304 except Exception: 305 FileCache.purge(self, id)
306
307 - def put(self, id, object):
308 if isinstance(object, Element): 309 FileCache.put(self, id, str(object)) 310 return object
311 312
313 -class ObjectCache(FileCache):
314 """ 315 Provides pickled object caching. 316 @cvar protocol: The pickling protocol. 317 @type protocol: int 318 """ 319 protocol = 2 320
321 - def fnsuffix(self):
322 return 'px'
323
324 - def get(self, id):
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):
335 bfr = pickle.dumps(object, self.protocol) 336 FileCache.put(self, id, bfr) 337 return object
338