summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--suds/cache.py50
-rw-r--r--suds/options.py8
-rw-r--r--suds/reader.py74
3 files changed, 94 insertions, 38 deletions
diff --git a/suds/cache.py b/suds/cache.py
index 0e2b314..c2bd624 100644
--- a/suds/cache.py
+++ b/suds/cache.py
@@ -21,6 +21,8 @@ Contains basic caching classes.
import os
from tempfile import gettempdir as tmp
from suds.transport import *
+from suds.sax.parser import Parser
+from suds.sax.element import Element
from datetime import datetime as dt
from datetime import timedelta
from cStringIO import StringIO
@@ -115,8 +117,6 @@ class FileCache(Cache):
"""
A file-based URL cache.
@cvar fnprefix: The file name prefix.
- @type fnprefix: str
- @ivar fnsuffix: The file name suffix.
@type fnsuffix: str
@ivar duration: The cached file duration which defines how
long the file will be cached.
@@ -125,7 +125,6 @@ class FileCache(Cache):
@type location: str
"""
fnprefix = 'suds'
- fnsuffix = 'gcf'
units = ('months', 'weeks', 'days', 'hours', 'minutes', 'seconds')
def __init__(self, location=None, **duration):
@@ -143,6 +142,14 @@ class FileCache(Cache):
self.duration = (None, 0)
self.setduration(**duration)
+ def fnsuffix(self):
+ """
+ Get the file name suffix
+ @return: The suffix
+ @rtype: str
+ """
+ return 'gcf'
+
def setduration(self, **duration):
"""
Set the caching duration which defines how long the
@@ -255,14 +262,34 @@ class FileCache(Cache):
return open(fn, *args)
def __fn(self, id):
- if hasattr(id, 'name') and hasattr(id, 'suffix'):
- name = id.name
- suffix = id.suffix
- else:
- name = id
- suffix = self.fnsuffix
- fn = '%s-%s.%s' % (self.fnprefix, abs(hash(name)), suffix)
+ name = id
+ suffix = self.fnsuffix()
+ fn = '%s-%s.%s' % (self.fnprefix, name, suffix)
return os.path.join(self.location, fn)
+
+
+class DocumentCache(FileCache):
+ """
+ Provides xml document caching.
+ """
+
+ def fnsuffix(self):
+ return 'xml'
+
+ def get(self, id):
+ try:
+ fp = FileCache.getf(self, id)
+ if fp is None:
+ return None
+ p = Parser()
+ return p.parse(fp)
+ except:
+ FileCache.purge(self, id)
+
+ def put(self, id, object):
+ if isinstance(object, Element):
+ FileCache.put(self, id, str(object))
+ return object
class ObjectCache(FileCache):
@@ -273,6 +300,9 @@ class ObjectCache(FileCache):
"""
protocol = 2
+ def fnsuffix(self):
+ return 'px'
+
def get(self, id):
try:
fp = FileCache.getf(self, id)
diff --git a/suds/options.py b/suds/options.py
index 7e5c069..4cf3660 100644
--- a/suds/options.py
+++ b/suds/options.py
@@ -85,9 +85,14 @@ class Options(Skin):
- type: I{bool}
- default: False
- B{autoblend} - Flag that ensures that the schema(s) defined within the
- WSDL import each other. B{**Experimental**}.
+ WSDL import each other.
- type: I{bool}
- default: False
+ - B{cachingpolicy} - The caching policy.
+ - type: I{int}
+ - 0 = Cache XML documents.
+ - 1 = Cache WSDL (pickled) object.
+ - default: 0
"""
def __init__(self, **kwargs):
domain = __name__
@@ -105,5 +110,6 @@ class Options(Skin):
Definition('prefixes', bool, True),
Definition('retxml', bool, False),
Definition('autoblend', bool, False),
+ Definition('cachingpolicy', int, 0),
]
Skin.__init__(self, domain, definitions, kwargs)
diff --git a/suds/reader.py b/suds/reader.py
index 84e6822..0bac400 100644
--- a/suds/reader.py
+++ b/suds/reader.py
@@ -21,6 +21,7 @@ Contains xml document reader classes.
from suds.sax.parser import Parser
from suds.transport import Request
+from suds.cache import Cache, NoCache
from suds.store import DocumentStore
from logging import getLogger
@@ -28,31 +29,34 @@ from logging import getLogger
log = getLogger(__name__)
-class ObjectId(object):
-
- def __init__(self, name, suffix):
- self.name = name
- self.suffix = suffix
-
-
-class DocumentReader:
+class Reader:
"""
- The XML document reader provides an integration
- between the SAX L{Parser} and the document cache.
- @cvar suffix: The cache file suffix.
- @type suffix: str
+ The reader provides integration with cache.
@ivar options: An options object.
@type options: I{Options}
"""
-
- suffix = 'pxd'
-
+
def __init__(self, options):
"""
@param options: An options object.
@type options: I{Options}
"""
self.options = options
+
+ def mangle(self, name, x):
+ """
+ Mangle the name by hashing the I{name} and appending I{x}.
+ @return: the mangled name.
+ """
+ h = abs(hash(name))
+ return '%s-%s' % (h, x)
+
+
+class DocumentReader(Reader):
+ """
+ The XML document reader provides an integration
+ between the SAX L{Parser} and the document cache.
+ """
def open(self, url):
"""
@@ -66,8 +70,8 @@ class DocumentReader:
@return: The specified XML document.
@rtype: I{Document}
"""
- id = ObjectId(url, self.suffix)
- cache = self.options.cache
+ cache = self.cache()
+ id = self.mangle(url, 'document')
d = cache.get(id)
if d is None:
d = self.download(url)
@@ -88,23 +92,28 @@ class DocumentReader:
fp = self.options.transport.open(Request(url))
sax = Parser()
return sax.parse(file=fp)
+
+ def cache(self):
+ """
+ Get the cache.
+ @return: The I{options} when I{cachingpolicy} = B{0}.
+ @rtype: L{Cache}
+ """
+ if self.options.cachingpolicy == 0:
+ return self.options.cache
+ else:
+ return NoCache()
-class DefinitionsReader:
+class DefinitionsReader(Reader):
"""
The WSDL definitions reader provides an integration
between the Definitions and the object cache.
- @cvar suffix: The cache file suffix.
- @type suffix: str
- @ivar options: An options object.
- @type options: I{Options}
@ivar fn: A factory function (constructor) used to
create the object not found in the cache.
@type fn: I{Constructor}
"""
- suffix = 'pw'
-
def __init__(self, options, fn):
"""
@param options: An options object.
@@ -113,7 +122,7 @@ class DefinitionsReader:
create the object not found in the cache.
@type fn: I{Constructor}
"""
- self.options = options
+ Reader.__init__(self, options)
self.fn = fn
def open(self, url):
@@ -129,8 +138,8 @@ class DefinitionsReader:
@return: The WSDL object.
@rtype: I{Definitions}
"""
- id = ObjectId(url, self.suffix)
- cache = self.options.cache
+ cache = self.cache()
+ id = self.mangle(url, 'wsdl')
d = cache.get(id)
if d is None:
d = self.fn(url, self.options)
@@ -140,3 +149,14 @@ class DefinitionsReader:
for imp in d.imports:
imp.imported.options = self.options
return d
+
+ def cache(self):
+ """
+ Get the cache.
+ @return: The I{options} when I{cachingpolicy} = B{1}.
+ @rtype: L{Cache}
+ """
+ if self.options.cachingpolicy == 1:
+ return self.options.cache
+ else:
+ return NoCache() \ No newline at end of file