mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 13:33:09 +00:00
dirnode.set_uri/set_children: change signature to take writecap+readcap
instead of a single cap. The webapi t=set_children call benefits too.
This commit is contained in:
parent
3ee740628a
commit
e2ffc3dc03
@ -380,19 +380,11 @@ class DirectoryNode:
|
||||
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
|
||||
@ -409,15 +401,16 @@ class DirectoryNode:
|
||||
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)
|
||||
|
@ -873,15 +873,19 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
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.
|
||||
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_uri could be for a file, or for a directory (either
|
||||
read-write or read-only, using a URI that came from get_uri() ).
|
||||
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
|
||||
@ -894,11 +898,11 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
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):
|
||||
|
@ -1186,8 +1186,8 @@ class Large(DeepCheckBase, unittest.TestCase):
|
||||
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, "")
|
||||
|
@ -67,6 +67,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
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)
|
||||
@ -159,7 +160,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
|
||||
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)
|
||||
@ -171,7 +172,7 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
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,
|
||||
@ -243,11 +244,13 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
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
|
||||
@ -373,12 +376,16 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
|
||||
# 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'))
|
||||
@ -387,7 +394,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
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()),
|
||||
@ -395,7 +403,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
|
||||
# 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:
|
||||
@ -439,17 +448,19 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
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())
|
||||
@ -645,7 +656,8 @@ class Dirnode(GridTestMixin, unittest.TestCase,
|
||||
|
||||
# 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",
|
||||
@ -804,7 +816,8 @@ class Dirnode2(unittest.TestCase, testutil.ShouldFailMixin):
|
||||
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)
|
||||
|
@ -862,8 +862,12 @@ class SystemTest(SystemTestMixin, unittest.TestCase):
|
||||
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)
|
||||
@ -944,7 +948,7 @@ class SystemTest(SystemTestMixin, unittest.TestCase):
|
||||
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"))
|
||||
|
||||
|
@ -136,37 +136,40 @@ class WebMixin(object):
|
||||
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/
|
||||
|
@ -204,7 +204,6 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
|
||||
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)
|
||||
@ -303,7 +302,7 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
|
||||
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
|
||||
|
||||
@ -471,8 +470,13 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user