instead of a single cap. The webapi t=set_children call benefits too.
d = self.get_child_and_metadata(childname)
return d
- def set_uri(self, name, child_uri, metadata=None, overwrite=True):
- """I add a child (by URI) at the specific name. I return a Deferred
- that fires with the child node when the operation finishes. I will
- replace any existing child of the same name.
-
- The child_uri could be for a file, or for a directory (either
- read-write or read-only, using a URI that came from get_uri() ).
-
- If this directory node is read-only, the Deferred will errback with a
- NotMutableError."""
+ def set_uri(self, name, writecap, readcap, metadata=None, overwrite=True):
precondition(isinstance(name, unicode), name)
- precondition(isinstance(child_uri, str), child_uri)
- child_node = self._create_node(child_uri, None)
+ precondition(isinstance(writecap, (str,type(None))), writecap)
+ precondition(isinstance(readcap, (str,type(None))), readcap)
+ child_node = self._create_node(writecap, readcap)
if isinstance(child_node, UnknownNode):
# don't be willing to pack unknown nodes: we might accidentally
# put some write-authority into the rocap slot because we don't
a = Adder(self, overwrite=overwrite)
node_entries = []
for e in entries:
- if len(e) == 2:
- name, child_uri = e
+ if len(e) == 3:
+ name, writecap, readcap = e
metadata = None
else:
- assert len(e) == 3
- name, child_uri, metadata = e
+ assert len(e) == 4
+ name, writecap, readcap, metadata = e
assert isinstance(name, unicode)
- assert isinstance(child_uri, str)
- child_node = self._create_node(child_uri, None)
+ precondition(isinstance(writecap, (str,type(None))), writecap)
+ precondition(isinstance(readcap, (str,type(None))), readcap)
+ child_node = self._create_node(writecap, readcap)
if isinstance(child_node, UnknownNode):
msg = "cannot pack unknown node as child %s" % str(name)
raise CannotPackUnknownNodeError(msg)
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
- replace any existing child of the same name, otherwise an existing
- child will cause me to return ExistingChildError. The child name must
- be a unicode string.
-
- The child_uri could be for a file, or for a directory (either
- read-write or read-only, using a URI that came from get_uri() ).
+ def set_uri(name, writecap, readcap=None, metadata=None, overwrite=True):
+ """I add a child (by writecap+readcap) at the specific name. I return
+ a Deferred that fires when the operation finishes. If overwrite= is
+ True, I will replace any existing child of the same name, otherwise
+ an existing child will cause me to return ExistingChildError. The
+ child name must be a unicode string.
+
+ The child caps could be for a file, or for a directory. If the new
+ child is read/write, you will provide both writecap and readcap. If
+ the child is read-only, you will provide the readcap write (i.e. the
+ writecap= and readcap= arguments will both be the child's readcap).
+ The filecaps are typically obtained from an IFilesystemNode with
+ get_uri() and get_readonly_uri().
If metadata= is provided, I will use it as the metadata for the named
edge. This will replace any existing metadata. If metadata= is left
NotMutableError."""
def set_children(entries, overwrite=True):
- """Add multiple (name, child_uri) pairs (or (name, child_uri,
- metadata) triples) to a directory node. Returns a Deferred that fires
- (with None) when the operation finishes. This is equivalent to
- calling set_uri() multiple times, but is much more efficient. All
- child names must be unicode strings.
+ """Add multiple (name, writecap, readcap) triples (or (name,
+ writecap, readcap, metadata) 4-tuples) to a directory node. Returns a
+ Deferred that fires (with None) when the operation finishes. This is
+ equivalent to calling set_uri() multiple times, but is much more
+ efficient. All child names must be unicode strings.
"""
def set_node(name, child, metadata=None, overwrite=True):
self.subdir_node = subdir_node
kids = []
for i in range(1, COUNT):
- litnode = LiteralFileURI("%03d-data" % i).to_string()
- kids.append( (u"%03d-small" % i, litnode) )
+ litcap = LiteralFileURI("%03d-data" % i).to_string()
+ kids.append( (u"%03d-small" % i, litcap, litcap) )
return subdir_node.set_children(kids)
d.addCallback(_add_children)
up = upload.Data("large enough for CHK" * 100, "")
d.addCallback(lambda res: c.create_dirnode())
d.addCallback(lambda dn:
self._rootnode.set_uri(u"rodir",
+ dn.get_uri(),
dn.get_readonly_uri()))
return d
d.addCallback(_created_subdir)
d = c.create_dirnode()
def _created(rw_dn):
- d2 = rw_dn.set_uri(u"child", filecap)
+ d2 = rw_dn.set_uri(u"child", filecap, filecap)
d2.addCallback(lambda res: rw_dn)
return d2
d.addCallback(_created)
self.failUnless(ro_dn.is_mutable())
self.shouldFail(dirnode.NotMutableError, "set_uri ro", None,
- ro_dn.set_uri, u"newchild", filecap)
+ ro_dn.set_uri, u"newchild", filecap, filecap)
self.shouldFail(dirnode.NotMutableError, "set_uri ro", None,
ro_dn.set_node, u"newchild", filenode)
self.shouldFail(dirnode.NotMutableError, "set_nodes ro", None,
self.expected_manifest.append( ((u"child",) , m.get_uri()) )
self.expected_verifycaps.add(ffu_v)
self.expected_storage_indexes.add(base32.b2a(m.get_storage_index()))
- d.addCallback(lambda res: n.set_uri(u"child", fake_file_uri))
+ d.addCallback(lambda res: n.set_uri(u"child",
+ fake_file_uri, fake_file_uri))
d.addCallback(lambda res:
self.shouldFail(ExistingChildError, "set_uri-no",
"child 'child' already exists",
- n.set_uri, u"child", other_file_uri,
+ n.set_uri, u"child",
+ other_file_uri, other_file_uri,
overwrite=False))
# /
# /child = mutable
# 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, {}))
+ d.addCallback(lambda res: n.set_uri(u"c2",
+ fake_file_uri, fake_file_uri,
+ {}))
d.addCallback(lambda res: n.get_metadata_for(u"c2"))
d.addCallback(lambda metadata: self.failUnlessEqual(metadata.keys(), ['tahoe']))
# You can't override the link timestamps.
- d.addCallback(lambda res: n.set_uri(u"c2", fake_file_uri, { 'tahoe': {'linkcrtime': "bogus"}}))
+ d.addCallback(lambda res: n.set_uri(u"c2",
+ fake_file_uri, fake_file_uri,
+ { 'tahoe': {'linkcrtime': "bogus"}}))
d.addCallback(lambda res: n.get_metadata_for(u"c2"))
def _has_good_linkcrtime(metadata):
self.failUnless(metadata.has_key('tahoe'))
d.addCallback(_has_good_linkcrtime)
# if we don't set any defaults, the child should get timestamps
- d.addCallback(lambda res: n.set_uri(u"c3", fake_file_uri))
+ d.addCallback(lambda res: n.set_uri(u"c3",
+ fake_file_uri, fake_file_uri))
d.addCallback(lambda res: n.get_metadata_for(u"c3"))
d.addCallback(lambda metadata:
self.failUnlessEqual(set(metadata.keys()),
# or we can add specific metadata at set_uri() time, which
# overrides the timestamps
- d.addCallback(lambda res: n.set_uri(u"c4", fake_file_uri,
+ d.addCallback(lambda res: n.set_uri(u"c4",
+ fake_file_uri, fake_file_uri,
{"key": "value"}))
d.addCallback(lambda res: n.get_metadata_for(u"c4"))
d.addCallback(lambda metadata:
d.addCallback(lambda res: n.delete(u"d4"))
# metadata through set_children()
- d.addCallback(lambda res: n.set_children([ (u"e1", fake_file_uri),
- (u"e2", fake_file_uri, {}),
- (u"e3", fake_file_uri,
- {"key": "value"}),
- ]))
+ d.addCallback(lambda res:
+ n.set_children([
+ (u"e1", fake_file_uri, fake_file_uri),
+ (u"e2", fake_file_uri, fake_file_uri, {}),
+ (u"e3", fake_file_uri, fake_file_uri,
+ {"key": "value"}),
+ ]))
d.addCallback(lambda res:
self.shouldFail(ExistingChildError, "set_children-no",
"child 'e1' already exists",
n.set_children,
- [ (u"e1", other_file_uri),
- (u"new", other_file_uri), ],
+ [ (u"e1", other_file_uri, other_file_uri),
+ (u"new", other_file_uri, other_file_uri), ],
overwrite=False))
# and 'new' should not have been created
d.addCallback(lambda res: n.list())
# now make sure that we honor overwrite=False
d.addCallback(lambda res:
- self.subdir2.set_uri(u"newchild", other_file_uri))
+ self.subdir2.set_uri(u"newchild",
+ other_file_uri, other_file_uri))
d.addCallback(lambda res:
self.shouldFail(ExistingChildError, "move_child_to-no",
self.shouldFail(CannotPackUnknownNodeError,
"copy unknown",
"cannot pack unknown node as child add",
- self._node.set_uri, u"add", future_writecap))
+ self._node.set_uri, u"add",
+ future_writecap, future_readcap))
d.addCallback(lambda ign: self._node.list())
def _check(children):
self.failUnlessEqual(len(children), 1)
d1.addCallback(self.log, "made P/personal/sekrit data")
d1.addCallback(lambda res: rootnode.get_child_at_path([u"subdir1", u"subdir2"]))
def _got_s2(s2node):
- d2 = privnode.set_uri(u"s2-rw", s2node.get_uri())
- d2.addCallback(lambda node: privnode.set_uri(u"s2-ro", s2node.get_readonly_uri()))
+ d2 = privnode.set_uri(u"s2-rw", s2node.get_uri(),
+ s2node.get_readonly_uri())
+ d2.addCallback(lambda node:
+ privnode.set_uri(u"s2-ro",
+ s2node.get_readonly_uri(),
+ s2node.get_readonly_uri()))
return d2
d1.addCallback(_got_s2)
d1.addCallback(lambda res: privnode)
d1.addCallback(self.log, "doing delete(ro)")
d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "delete(nope)", None, dirnode.delete, u"mydata992"))
- d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "set_uri(nope)", None, dirnode.set_uri, u"hopeless", self.uri))
+ d1.addCallback(lambda res: self.shouldFail2(NotMutableError, "set_uri(nope)", None, dirnode.set_uri, u"hopeless", self.uri, self.uri))
d1.addCallback(lambda res: self.shouldFail2(NoSuchChildError, "get(missing)", "missing", dirnode.get, u"missing"))
self._foo_verifycap = foo.get_verify_cap().to_string()
# NOTE: we ignore the deferred on all set_uri() calls, because we
# know the fake nodes do these synchronously
- self.public_root.set_uri(u"foo", foo.get_uri())
+ self.public_root.set_uri(u"foo", foo.get_uri(),
+ foo.get_readonly_uri())
self.BAR_CONTENTS, n, self._bar_txt_uri = self.makefile(0)
- foo.set_uri(u"bar.txt", self._bar_txt_uri)
+ foo.set_uri(u"bar.txt", self._bar_txt_uri, self._bar_txt_uri)
self._bar_txt_verifycap = n.get_verify_cap().to_string()
- foo.set_uri(u"empty", res[3][1].get_uri())
+ foo.set_uri(u"empty", res[3][1].get_uri(),
+ res[3][1].get_readonly_uri())
sub_uri = res[4][1].get_uri()
self._sub_uri = sub_uri
- foo.set_uri(u"sub", sub_uri)
+ foo.set_uri(u"sub", sub_uri, sub_uri)
sub = self.s.create_node_from_uri(sub_uri)
_ign, n, blocking_uri = self.makefile(1)
- foo.set_uri(u"blockingfile", blocking_uri)
+ foo.set_uri(u"blockingfile", blocking_uri, blocking_uri)
unicode_filename = u"n\u00fc.txt" # n u-umlaut . t x t
# ok, unicode calls it LATIN SMALL LETTER U WITH DIAERESIS but I
# still think of it as an umlaut
- foo.set_uri(unicode_filename, self._bar_txt_uri)
+ foo.set_uri(unicode_filename, self._bar_txt_uri, self._bar_txt_uri)
_ign, n, baz_file = self.makefile(2)
self._baz_file_uri = baz_file
- sub.set_uri(u"baz.txt", baz_file)
+ sub.set_uri(u"baz.txt", baz_file, baz_file)
_ign, n, self._bad_file_uri = self.makefile(3)
# this uri should not be downloadable
del FakeCHKFileNode.all_contents[self._bad_file_uri]
rodir = res[5][1]
- self.public_root.set_uri(u"reedownlee", rodir.get_readonly_uri())
- rodir.set_uri(u"nor", baz_file)
+ self.public_root.set_uri(u"reedownlee", rodir.get_readonly_uri(),
+ rodir.get_readonly_uri())
+ rodir.set_uri(u"nor", baz_file, baz_file)
# public/
# public/foo/
elif t == "stream-manifest":
d = self._POST_stream_manifest(ctx)
elif t == "set_children":
- # TODO: docs
d = self._POST_set_children(req)
else:
raise WebError("POST to a directory with bad t=%s" % t)
charset = get_arg(req, "_charset", "utf-8")
name = name.decode(charset)
replace = boolean_of_arg(get_arg(req, "replace", "true"))
- d = self.node.set_uri(name, childcap, overwrite=replace)
+ d = self.node.set_uri(name, childcap, childcap, overwrite=replace)
d.addCallback(lambda res: childcap)
return d
cs = []
for name, (file_or_dir, mddict) in children.iteritems():
name = unicode(name) # simplejson-2.0.1 returns str *or* unicode
- cap = str(mddict.get('rw_uri') or mddict.get('ro_uri'))
- cs.append((name, cap, mddict.get('metadata')))
+ writecap = mddict.get('rw_uri')
+ if writecap is not None:
+ writecap = str(writecap)
+ readcap = mddict.get('ro_uri')
+ if readcap is not None:
+ readcap = str(readcap)
+ cs.append((name, writecap, readcap, mddict.get('metadata')))
d = self.node.set_children(cs, replace)
d.addCallback(lambda res: "Okay so I did it.")
# TODO: results