Change the arbitrary URI support from implied to explicit

The move webapi function now takes a target_type argument which lets it
know whether the target is a subdirectory name or URI. This is an
improvement over the old system in which the move handler tried to guess
whether the target was a name or a URI. Also fixed a little docs
copypaste problem and tweaked some line wrapping.
This commit is contained in:
Marcus Wanner 2011-11-18 20:42:10 -05:00 committed by Brian Warner
parent b29d0920d3
commit e58a01270b
5 changed files with 47 additions and 26 deletions

View File

@ -1281,16 +1281,21 @@ Renaming A Child
Moving A Child
----------------
``POST /uri/$DIRCAP/[SUBDIRS../]?t=rename&from_name=OLD&to_dir=TARGET[&to_name=NEW]``
``POST /uri/$DIRCAP/[SUBDIRS../]?t=move&from_name=OLD&to_dir=TARGET``
This instructs the node to move a child of the given directory to a
different directory, both of which must be mutable. The child can also be
renamed in the process. The to_dir parameter can be either the name of a
subdirectory of the dircap from which the child is being moved (multiple
levels of descent are supported) or the writecap of an unrelated directory.
different directory, both of which must be mutable. The child can also
be renamed in the process. The to_dir parameter should contain the name
of a subdirectory of the dircap from which the child is being moved
(multiple levels of descent are supported), unless the file is to be
moved to an unrelated directory. In the latter case, this can be
specified by passing a target_type=uri argument and the target URI in
to_dir=. If the target is the name of a subdirectory, this can be
signified by passing target_type=name. A new name for the child can
also be specified using the to_name= parameter.
This operation will replace any existing child of the new name, making it
behave like the UNIX "``mv -f``" command. The original child is not
This operation will replace any existing child of the new name, making
it behave like the UNIX "``mv -f``" command. The original child is not
unlinked until it is linked into the target directory.
Other Utilities

View File

@ -3247,7 +3247,6 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
return d
def test_POST_move_file(self):
""""""
d = self.POST(self.public_url + "/foo", t="move",
from_name="bar.txt", to_dir="sub")
d.addCallback(lambda res:
@ -3331,6 +3330,16 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
d.addCallback(self.failUnlessIsBazDotTxt)
return d
def test_POST_move_file_bad_target_type(self):
d = self.POST(self.public_url + "/foo", t="move", target_type="*D",
from_name="bar.txt", to_dir="sub")
d.addBoth(self.shouldFail, error.Error,
"test_POST_rename_file_slash_fail",
"400 Bad Request",
"invalid target_type parameter",
)
return d
def test_POST_move_file_multi_level(self):
d = self.POST(self.public_url + "/foo/sub/level2?t=mkdir", "")
d.addCallback(lambda res: self.POST(self.public_url + "/foo", t="move",
@ -3344,7 +3353,7 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
return d
def test_POST_move_file_to_uri(self):
d = self.POST(self.public_url + "/foo", t="move",
d = self.POST(self.public_url + "/foo", t="move", target_type="uri",
from_name="bar.txt", to_dir=self._sub_uri)
d.addCallback(lambda res:
self.failIfNodeHasChild(self._foo_node, u"bar.txt"))
@ -3379,7 +3388,8 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi
return d
def test_POST_move_file_to_bad_uri(self):
d = self.POST(self.public_url + "/foo", t="move", from_name="bar.txt",
d = self.POST(self.public_url + "/foo", t="move",
from_name="bar.txt", target_type="uri",
to_dir="URI:DIR2:mn5jlyjnrjeuydyswlzyui72i:rmneifcj6k6sycjljjhj3f6majsq2zqffydnnul5hfa4j577arma")
d.addBoth(self.shouldFail, error.Error,
"POST_move_file_to_bad_uri",

View File

@ -934,13 +934,6 @@ def is_literal_file_uri(s):
s.startswith(ALLEGED_READONLY_PREFIX + 'URI:LIT:') or
s.startswith(ALLEGED_IMMUTABLE_PREFIX + 'URI:LIT:'))
def is_writeable_directory_uri(s):
if not isinstance(s, str):
return False
return (s.startswith('URI:DIR2:') or
s.startswith(ALLEGED_READONLY_PREFIX + 'URI:DIR2:') or
s.startswith(ALLEGED_IMMUTABLE_PREFIX + 'URI:DIR2:'))
def has_uri_prefix(s):
if not isinstance(s, str):
return False

View File

@ -13,7 +13,7 @@ from nevow.inevow import IRequest
from foolscap.api import fireEventually
from allmydata.util import base32, time_format
from allmydata.uri import from_string_dirnode, is_writeable_directory_uri
from allmydata.uri import from_string_dirnode
from allmydata.interfaces import IDirectoryNode, IFileNode, IFilesystemNode, \
IImmutableFileNode, IMutableFileNode, ExistingChildError, \
NoSuchChildError, EmptyPathnameComponentError, SDMF_VERSION, MDMF_VERSION
@ -444,23 +444,30 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin):
if not from_name or not to_dir:
raise WebError("move requires from_name and to_dir")
replace = boolean_of_arg(get_arg(req, "replace", "true"))
target_type = get_arg(req, "target_type", "name")
if not target_type in ["name", "uri"]:
raise WebError("invalid target_type parameter",
http.BAD_REQUEST)
# allow from_name to contain slashes, so they can fix names that
# were accidentally created with them. But disallow them in to_name
# (if it's specified), to discourage the practice.
if to_name and "/" in to_name:
raise WebError("to_name= may not contain a slash", http.BAD_REQUEST)
raise WebError("to_name= may not contain a slash",
http.BAD_REQUEST)
d = self.node.has_child(to_dir.split('/')[0])
def get_target_node(isname):
if isname or not is_writeable_directory_uri(str(to_dir)):
d = defer.Deferred()
def get_target_node(target_type):
if target_type == "name":
return self.node.get_child_at_path(to_dir)
else:
elif target_type == "uri":
return self.client.create_node_from_uri(str(to_dir))
d.addCallback(get_target_node)
d.callback(target_type)
def is_target_node_usable(target_node):
if not IDirectoryNode.providedBy(target_node):
raise WebError("to_dir is not a usable directory", http.GONE)
raise WebError("to_dir is not a usable directory",
http.GONE)
return target_node
d.addCallback(is_target_node_usable)
d.addCallback(lambda new_parent: self.node.move_child_to(

View File

@ -17,12 +17,18 @@
<input n:render="when_done" />
Move child:
<input type="text" name="from_name" readonly="true" n:render="get_name" />
<input type="text" name="from_name" readonly="true"
n:render="get_name" /><br />
to
<input type="text" name="to_dir" /><br />
<input checked="checked" type="radio" id="tt-name"
value="name" name="target_type" />
<label for="tt-name"> Subdirectory</label>
<input type="radio" id="tt-uri" value="uri" name="target_type"/>
<label for="tt-uri"> URI</label> <br /><br />
New name?
<input type="text" name="to_name" />
<input type="submit" value="move" />
<input type="submit" value="move" /><br />
</fieldset>
</form>
</div>