raise KeyError(name)
return child[0]
+ def _get_with_metadata(self, children, name):
+ child = children.get(name)
+ if child is None:
+ raise KeyError(name)
+ return child
+
def get(self, name):
"""I return a Deferred that fires with the named child node,
which is either an IFileNode or an IDirectoryNode."""
d.addCallback(self._get, name)
return d
+ def get_child_and_metadata(self, name):
+ """I return a Deferred that fires with the (node, metadata) pair for
+ the named child. The node is either an IFileNode or an
+ IDirectoryNode, and the metadata is a dictionary."""
+ assert isinstance(name, unicode)
+ d = self._read()
+ d.addCallback(self._get_with_metadata, name)
+ return d
+
def get_metadata_for(self, name):
assert isinstance(name, unicode)
d = self._read()
The path can be either a single string (slash-separated) or a list of
path-name elements.
"""
+ d = self.get_child_and_metdadata_at_path(path)
+ d.addCallback(lambda (node, metadata): node)
+ return d
+
+ def get_child_and_metdadata_at_path(self, path):
+ """Transform a child path into an IDirectoryNode or IFileNode and
+ a metadata dictionary from the last edge that was traversed.
+ """
if not path:
- return defer.succeed(self)
+ return defer.succeed((self, {}))
if isinstance(path, (list, tuple)):
pass
else:
assert isinstance(p, unicode)
childname = path[0]
remaining_path = path[1:]
- d = self.get(childname)
if remaining_path:
- def _got(node):
- return node.get_child_at_path(remaining_path)
- d.addCallback(_got)
+ d = self.get(childname)
+ d.addCallback(lambda node:
+ node.get_child_and_metdadata_at_path(remaining_path))
+ return d
+ d = self.get_child_and_metadata(childname)
return d
def set_uri(self, name, child_uri, metadata=None, overwrite=True):
path-name elements. All elements must be unicode strings.
"""
+ def get_child_and_metadata_at_path(path):
+ """Transform a child path into an IDirectoryNode/IFileNode and
+ metadata.
+
+ I am like get_child_at_path(), but my Deferred fires with a tuple of
+ (node, metadata). The metadata comes from the last edge. If the path
+ is empty, the metadata will be an empty dictionary.
+ """
+
def set_uri(name, child_uri, metadata=None, overwrite=True):
"""I add a child (by URI) at the specific name. I return a Deferred
that fires when the operation finishes. If overwrite= is True, I will
def _add_subsubdir(res):
return self.subdir.create_empty_directory(u"subsubdir")
d.addCallback(_add_subsubdir)
+ # /
+ # /child = mutable
+ # /subdir = directory
+ # /subdir/subsubdir = directory
d.addCallback(lambda res: n.get_child_at_path(u"subdir/subsubdir"))
d.addCallback(lambda subsubdir:
self.failUnless(isinstance(subsubdir,
self.failUnlessEqual(sorted(metadata.keys()),
["ctime", "mtime"]))
+ d.addCallback(lambda res:
+ self.shouldFail(KeyError, "gcamap-no",
+ "'nope'",
+ n.get_child_and_metdadata_at_path,
+ u"subdir/nope"))
+ d.addCallback(lambda res:
+ n.get_child_and_metdadata_at_path(u""))
+ def _check_child_and_metadata1(res):
+ child, metadata = res
+ self.failUnless(isinstance(child, FakeDirectoryNode))
+ # edge-metadata needs at least one path segment
+ self.failUnlessEqual(sorted(metadata.keys()), [])
+ d.addCallback(_check_child_and_metadata1)
+ d.addCallback(lambda res:
+ n.get_child_and_metdadata_at_path(u"child"))
+
+ def _check_child_and_metadata2(res):
+ child, metadata = res
+ self.failUnlessEqual(child.get_uri(),
+ fake_file_uri.to_string())
+ self.failUnlessEqual(sorted(metadata.keys()),
+ ["ctime", "mtime"])
+ d.addCallback(_check_child_and_metadata2)
+
+ d.addCallback(lambda res:
+ n.get_child_and_metdadata_at_path(u"subdir/subsubdir"))
+ def _check_child_and_metadata3(res):
+ child, metadata = res
+ self.failUnless(isinstance(child, FakeDirectoryNode))
+ self.failUnlessEqual(sorted(metadata.keys()),
+ ["ctime", "mtime"])
+ d.addCallback(_check_child_and_metadata3)
+
# set_uri + metadata
# it should be possible to add a child without any metadata
d.addCallback(lambda res: n.set_uri(u"c2", fake_file_uri, {}))