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