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: 
 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: 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
213 - def get(self, id):
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
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 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
254 - def purge(self, id):
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
268 - def checkversion(self):
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
290 -class DocumentCache(FileCache):
291 """ 292 Provides xml document caching. 293 """ 294
295 - def fnsuffix(self):
296 return 'xml'
297
298 - def get(self, id):
299 try: 300 fp = FileCache.getf(self, id) 301 if fp is None: 302 return None 303 p = Parser() 304 return p.parse(fp) 305 except: 306 FileCache.purge(self, id)
307
308 - def put(self, id, object):
309 if isinstance(object, Element): 310 FileCache.put(self, id, str(object)) 311 return object
312 313
314 -class ObjectCache(FileCache):
315 """ 316 Provides pickled object caching. 317 @cvar protocol: The pickling protocol. 318 @type protocol: int 319 """ 320 protocol = 2 321
322 - def fnsuffix(self):
323 return 'px'
324
325 - def get(self, id):
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):
336 bfr = pickle.dumps(object, self.protocol) 337 FileCache.put(self, id, bfr) 338 return object
339