mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 21:43:09 +00:00
wapi: add POST /uri/$DIRECTORY?t=set_children
Unfinished bits: doc in webapi.txt, test handling of badly formed JSON, return reasonable HTTP response, examination of the effect of this patch on code coverage -- but I'm committing it anyway because MikeB can use it and I'm being called to dinner...
This commit is contained in:
parent
5cdc678d24
commit
99f006c584
@ -250,7 +250,7 @@ class NewDirectoryNode:
|
||||
assert isinstance(name, unicode)
|
||||
return self.set_node(name, self._create_node(child_uri), metadata)
|
||||
|
||||
def set_uris(self, entries):
|
||||
def set_children(self, entries):
|
||||
node_entries = []
|
||||
for e in entries:
|
||||
if len(e) == 2:
|
||||
|
@ -669,7 +669,7 @@ class IDirectoryNode(IMutableFilesystemNode):
|
||||
If this directory node is read-only, the Deferred will errback with a
|
||||
NotMutableError."""
|
||||
|
||||
def set_uris(entries):
|
||||
def set_children(entries):
|
||||
"""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
|
||||
|
@ -110,7 +110,7 @@ def make_verifier_uri():
|
||||
return uri.SSKVerifierURI(storage_index=os.urandom(16),
|
||||
fingerprint=os.urandom(32))
|
||||
|
||||
class NonGridDirectoryNode(dirnode.NewDirectoryNode):
|
||||
class FakeDirectoryNode(dirnode.NewDirectoryNode):
|
||||
"""This offers IDirectoryNode, but uses a FakeMutableFileNode for the
|
||||
backing store, so it doesn't go to the grid. The child data is still
|
||||
encrypted and serialized, so this isn't useful for tests that want to
|
||||
|
@ -7,15 +7,13 @@ from allmydata.interfaces import IURI, IClient, IMutableFileNode, \
|
||||
INewDirectoryURI, IReadonlyNewDirectoryURI, IFileNode
|
||||
from allmydata.util import hashutil, testutil
|
||||
from allmydata.test.common import make_chk_file_uri, make_mutable_file_uri, \
|
||||
NonGridDirectoryNode, create_chk_filenode
|
||||
FakeDirectoryNode, create_chk_filenode
|
||||
from twisted.internet import defer, reactor
|
||||
|
||||
# to test dirnode.py, we want to construct a tree of real DirectoryNodes that
|
||||
# contain pointers to fake files. We start with a fake MutableFileNode that
|
||||
# stores all of its data in a static table.
|
||||
|
||||
FakeDirectoryNode = NonGridDirectoryNode
|
||||
|
||||
class Marker:
|
||||
implements(IFileNode, IMutableFileNode) # sure, why not
|
||||
def __init__(self, nodeuri):
|
||||
@ -281,8 +279,8 @@ class Dirnode(unittest.TestCase, testutil.ShouldFailMixin):
|
||||
d.addCallback(lambda res: n.delete(u"d3"))
|
||||
d.addCallback(lambda res: n.delete(u"d4"))
|
||||
|
||||
# metadata through set_uris()
|
||||
d.addCallback(lambda res: n.set_uris([ (u"e1", fake_file_uri),
|
||||
# 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"}),
|
||||
|
@ -7,7 +7,7 @@ from twisted.web import client, error, http
|
||||
from twisted.python import failure, log
|
||||
from allmydata import interfaces, provisioning, uri, webish, upload, download
|
||||
from allmydata.util import fileutil
|
||||
from allmydata.test.common import NonGridDirectoryNode, FakeCHKFileNode, FakeMutableFileNode, create_chk_filenode
|
||||
from allmydata.test.common import FakeDirectoryNode, FakeCHKFileNode, FakeMutableFileNode, create_chk_filenode
|
||||
from allmydata.interfaces import IURI, INewDirectoryURI, IReadonlyNewDirectoryURI, IFileURI, IMutableFileURI, IMutableFileNode
|
||||
|
||||
# create a fake uploader/downloader, and a couple of fake dirnodes, then
|
||||
@ -35,18 +35,18 @@ class FakeClient(service.MultiService):
|
||||
def connected_to_introducer(self):
|
||||
return False
|
||||
|
||||
def create_node_from_uri(self, uri):
|
||||
u = IURI(uri)
|
||||
def create_node_from_uri(self, auri):
|
||||
u = uri.from_string(auri)
|
||||
if (INewDirectoryURI.providedBy(u)
|
||||
or IReadonlyNewDirectoryURI.providedBy(u)):
|
||||
return NonGridDirectoryNode(self).init_from_uri(u)
|
||||
return FakeDirectoryNode(self).init_from_uri(u)
|
||||
if IFileURI.providedBy(u):
|
||||
return FakeCHKFileNode(u, self)
|
||||
assert IMutableFileURI.providedBy(u), u
|
||||
return FakeMutableFileNode(self).init_from_uri(u)
|
||||
|
||||
def create_empty_dirnode(self):
|
||||
n = NonGridDirectoryNode(self)
|
||||
n = FakeDirectoryNode(self)
|
||||
d = n.create()
|
||||
d.addCallback(lambda res: n)
|
||||
return d
|
||||
@ -1299,6 +1299,46 @@ class Web(WebMixin, unittest.TestCase):
|
||||
d.addCallback(self.failUnlessNodeKeysAre, [])
|
||||
return d
|
||||
|
||||
def test_POST_set_children(self):
|
||||
contents9, n9, newuri9 = self.makefile(9)
|
||||
contents10, n10, newuri10 = self.makefile(10)
|
||||
contents11, n11, newuri11 = self.makefile(11)
|
||||
|
||||
reqbody = """{
|
||||
"atomic_added_1": [ "filenode", { "rw_uri": "%s",
|
||||
"size": 0,
|
||||
"metadata": {
|
||||
"ctime": 1002777696.7564139,
|
||||
"mtime": 1002777696.7564139
|
||||
}
|
||||
} ],
|
||||
"atomic_added_2": [ "filenode", { "rw_uri": "%s",
|
||||
"size": 1,
|
||||
"metadata": {
|
||||
"ctime": 1002777696.7564139,
|
||||
"mtime": 1002777696.7564139
|
||||
}
|
||||
} ],
|
||||
"atomic_added_3": [ "filenode", { "rw_uri": "%s",
|
||||
"size": 2,
|
||||
"metadata": {
|
||||
"ctime": 1002777696.7564139,
|
||||
"mtime": 1002777696.7564139
|
||||
}
|
||||
} ]
|
||||
}""" % (newuri9, newuri10, newuri11)
|
||||
|
||||
url = self.webish_url + self.public_url + "/foo" + "?t=set_children"
|
||||
|
||||
d = client.getPage(url, method="POST", postdata=reqbody)
|
||||
def _then(res):
|
||||
self.failUnlessURIMatchesChild(newuri9, self._foo_node, u"atomic_added_1")
|
||||
self.failUnlessURIMatchesChild(newuri10, self._foo_node, u"atomic_added_2")
|
||||
self.failUnlessURIMatchesChild(newuri11, self._foo_node, u"atomic_added_3")
|
||||
|
||||
d.addCallback(_then)
|
||||
return d
|
||||
|
||||
def test_POST_put_uri(self):
|
||||
contents, n, newuri = self.makefile(8)
|
||||
d = self.POST(self.public_url + "/foo", t="uri", name="new.txt", uri=newuri)
|
||||
|
@ -899,6 +899,16 @@ class POSTHandler(rend.Page):
|
||||
d.addCallback(_got_child_check)
|
||||
return d
|
||||
|
||||
def _POST_set_children(self, children):
|
||||
cs = []
|
||||
for name, (file_or_dir, mddict) in children.iteritems():
|
||||
cap = str(mddict.get('rw_uri') or mddict.get('ro_uri'))
|
||||
cs.append((name, cap, mddict.get('metadata')))
|
||||
|
||||
d = self._node.set_children(cs)
|
||||
d.addCallback(lambda res: "Okay so I did it.")
|
||||
return d
|
||||
|
||||
def renderHTTP(self, ctx):
|
||||
req = inevow.IRequest(ctx)
|
||||
|
||||
@ -973,16 +983,16 @@ class POSTHandler(rend.Page):
|
||||
d = self._POST_overwrite(contents)
|
||||
elif t == "check":
|
||||
d = self._POST_check(name)
|
||||
# elif t == "set_children":
|
||||
# d = self._POST_set_(name)
|
||||
# if not name:
|
||||
# raise RuntimeError("set-uri requires a name")
|
||||
# newuri = get_arg(req, "uri")
|
||||
# assert newuri is not None
|
||||
# d = self._check_replacement(name)
|
||||
# d.addCallback(lambda res: self._node.set_uri(name, newuri))
|
||||
# d.addCallback(lambda res: newuri)
|
||||
|
||||
elif t == "set_children":
|
||||
req.content.seek(0)
|
||||
body = req.content.read()
|
||||
try:
|
||||
children = simplejson.loads(body)
|
||||
except ValueError, le:
|
||||
le.args = tuple(le.args + (body,))
|
||||
# TODO test handling of bad JSON
|
||||
raise
|
||||
d = self._POST_set_children(children)
|
||||
else:
|
||||
print "BAD t=%s" % t
|
||||
return "BAD t=%s" % t
|
||||
@ -1346,9 +1356,8 @@ class UnlinkedPUTSSKUploader(rend.Page):
|
||||
req = inevow.IRequest(ctx)
|
||||
assert req.method == "PUT"
|
||||
# SDMF: files are small, and we can only upload data
|
||||
contents = req.content
|
||||
contents.seek(0)
|
||||
data = contents.read()
|
||||
req.content.seek(0)
|
||||
data = req.content.read()
|
||||
d = IClient(ctx).create_mutable_file(data)
|
||||
d.addCallback(lambda n: n.get_uri())
|
||||
return d
|
||||
|
Loading…
Reference in New Issue
Block a user