[Checkins] SVN: z3c.extfile/trunk/ fallbacks implemented

Bernd Dorn bernd.dorn at lovelysystems.com
Mon Jun 21 04:11:23 EDT 2010


Log message for revision 113720:
  fallbacks implemented

Changed:
  U   z3c.extfile/trunk/CHANGES.txt
  U   z3c.extfile/trunk/src/z3c/extfile/hashdir.py
  U   z3c.extfile/trunk/src/z3c/extfile/hashdir.txt
  U   z3c.extfile/trunk/src/z3c/extfile/zcml.py
  U   z3c.extfile/trunk/src/z3c/extfile/zcml.txt

-=-
Modified: z3c.extfile/trunk/CHANGES.txt
===================================================================
--- z3c.extfile/trunk/CHANGES.txt	2010-06-21 07:37:56 UTC (rev 113719)
+++ z3c.extfile/trunk/CHANGES.txt	2010-06-21 08:11:23 UTC (rev 113720)
@@ -5,6 +5,9 @@
 unreleased
 ==========
 
+- allow fallbacks in IHashDir for read-only access to additional
+  digest files. see hashdir.txt for details.
+
 - removed zope.tread and use threading instead
 
 0.2.0b2 (2008-07-14)

Modified: z3c.extfile/trunk/src/z3c/extfile/hashdir.py
===================================================================
--- z3c.extfile/trunk/src/z3c/extfile/hashdir.py	2010-06-21 07:37:56 UTC (rev 113719)
+++ z3c.extfile/trunk/src/z3c/extfile/hashdir.py	2010-06-21 08:11:23 UTC (rev 113720)
@@ -16,8 +16,9 @@
     interface.implements(interfaces.IHashDir)
     _path = None
 
-    def __init__(self, path=None):
+    def __init__(self, path=None, fallbacks=()):
         self.path = path
+        self.fallbacks = map(os.path.abspath, fallbacks)
 
     def _setPath(self, path):
         if path is None:
@@ -64,10 +65,11 @@
             raise ValueError, repr(digest)
         if type(self.var) is UnicodeType:
             digest = unicode(digest)
-        path = os.path.join(self.var, digest)
-        if not os.path.isfile(path):
-            raise KeyError, digest
-        return path
+        for base in [self.var] +  self.fallbacks:
+            path = os.path.join(base, digest)
+            if os.path.isfile(path):
+                return path
+        raise KeyError, digest
 
     def getSize(self, digest):
         return os.path.getsize(self.getPath(digest))

Modified: z3c.extfile/trunk/src/z3c/extfile/hashdir.txt
===================================================================
--- z3c.extfile/trunk/src/z3c/extfile/hashdir.txt	2010-06-21 07:37:56 UTC (rev 113719)
+++ z3c.extfile/trunk/src/z3c/extfile/hashdir.txt	2010-06-21 08:11:23 UTC (rev 113720)
@@ -145,11 +145,37 @@
   ValueError: 'abc'
 
 If we have a valid digest but it is not there a KeyError is raised.
+
   >>> hd.getPath('da39a3ee5e6b4b0d3255bfef95601890afd80700')
   Traceback (most recent call last):
   ...
   KeyError: 'da39a3ee5e6b4b0d3255bfef95601890afd80700'
 
+Fallbacks
+=========
+
+It is possible to set additional fallback paths upon hashdir creation,
+in order to have read-only fallback access to other extfile
+direcotires. This is usefull to allow a read-only directory to act as
+a static shared store.
+
+Let's create a new hasdhdir, with the previous hashdir's var path as
+fallback.
+
+  >>> hdPath2 = os.path.join(tmp, 'testhashdir2')
+  >>> hd2 = hashdir.HashDir(hdPath2, fallbacks=(hd.var,))
+
+It is now possible to get all digests from the fallback.
+
+  >>> f = hd2.open('0db0e5fa1ecf3e7659504f2e4048434cd9f20d2d')
+  >>> f.read()
+  'Content 2'
+
+Note that the fallback digests are not listet in the digests.
+
+  >>> hd2.digests()
+  []
+
 Cleanup
 
   >>> import shutil

Modified: z3c.extfile/trunk/src/z3c/extfile/zcml.py
===================================================================
--- z3c.extfile/trunk/src/z3c/extfile/zcml.py	2010-06-21 07:37:56 UTC (rev 113719)
+++ z3c.extfile/trunk/src/z3c/extfile/zcml.py	2010-06-21 08:11:23 UTC (rev 113720)
@@ -21,7 +21,7 @@
 from zope import interface
 from zope import schema
 from zope.component import zcml
-from zope.configuration.fields import Path
+from zope.configuration.fields import Path, Tokens
 from interfaces import IHashDir
 from z3c.extfile import hashdir
 
@@ -31,10 +31,14 @@
     path = Path(title = u'Path',
                 required=True)
 
-def hashDirDirective(_context, path, permission=None):
+    fallbacks = Tokens(title = u'Fallbacks',
+                       value_type=path,
+                       required=False)
+
+def hashDirDirective(_context, path, fallbacks=(), permission=None):
     """Function to create hashdir utility"""
 
-    util = hashdir.HashDir(path)
+    util = hashdir.HashDir(path, fallbacks=fallbacks)
     zcml.utility(_context,
                  provides=IHashDir,
                  component=util,

Modified: z3c.extfile/trunk/src/z3c/extfile/zcml.txt
===================================================================
--- z3c.extfile/trunk/src/z3c/extfile/zcml.txt	2010-06-21 07:37:56 UTC (rev 113719)
+++ z3c.extfile/trunk/src/z3c/extfile/zcml.txt	2010-06-21 08:11:23 UTC (rev 113720)
@@ -9,7 +9,7 @@
   ...    xmlns='http://namespaces.zope.org/zope'
   ...    xmlns:test='http://www.zope.org/NS/Zope3/test'
   ...    i18n_domain='zope'>
-  ...    <hashDir path="%s"/>
+  ...    <hashDir path="%s" fallbacks="%s"/>
   ...   </configure>"""
 
   >>> from zope.configuration.xmlconfig import xmlconfig, XMLConfig
@@ -23,19 +23,19 @@
 
   >>> from StringIO import StringIO
   >>> path = "./its/not/there"
-  >>> xmlconfig(StringIO(baseTemplate % path))
+  >>> xmlconfig(StringIO(baseTemplate % (path, '')))
   Traceback (most recent call last):
   ...
   ZopeXMLConfigurationError: ...
         OSError: ... No such file or directory: '.../its/not/there'
 
-We need an existing path.
+We need an existing path. We also define some fallbacks.
 
   >>> from zope import component
   >>> from z3c.extfile.interfaces import IHashDir
   >>> import tempfile, os, shutil
   >>> tmp1 = tempfile.mkdtemp()
-  >>> xmlconfig(StringIO(baseTemplate % tmp1))
+  >>> xmlconfig(StringIO(baseTemplate % (tmp1, '/tmp some/relative/path')))
   >>> sorted(os.listdir(tmp1))
   ['tmp', 'var']
   >>> util = component.getUtility(IHashDir)
@@ -45,7 +45,10 @@
   >>> util.path == tmp1
   True
 
+The fallback paths.
 
+  >>> util.fallbacks
+  [u'/tmp', u'/.../parts/.../some/relative/path']
 
 Also the bootstrapsubscriber looks if the utility is already
 registered and issues a warning if so and returns without any action.



More information about the checkins mailing list