From: david-sarah Date: Wed, 13 Jul 2011 00:12:18 +0000 (-0700) Subject: WUI: change the label of the button to unlink a file from 'del' to 'unlink'. Also... X-Git-Url: https://git.rkrishnan.org/Site/Content/Exhibitors/class-simplejson.JSONDecoder-index.html?a=commitdiff_plain;h=07ecac1d834ffd14c410c1277607baf3386ab385;p=tahoe-lafs%2Ftahoe-lafs.git WUI: change the label of the button to unlink a file from 'del' to 'unlink'. Also change some internal names to 'unlink', and allow 't=unlink' as a synonym for 't=delete' in the web-API interface. Incidentally, improve a test to check for the rename button as well as the unlink button. fixes #1104 --- diff --git a/docs/frontends/webapi.rst b/docs/frontends/webapi.rst index ea6ada67..ed591b62 100644 --- a/docs/frontends/webapi.rst +++ b/docs/frontends/webapi.rst @@ -88,7 +88,7 @@ URL) will return information about the object, such as metadata. GET operations are required to have no side-effects. PUT is used to upload new objects into the filesystem, or to replace an -existing object. DELETE it used to delete objects from the filesystem. Both +existing object. DELETE is used to delete objects from the filesystem. Both PUT and DELETE are required to be idempotent: performing the same operation multiple times must have the same side-effects as only performing it once. @@ -1159,6 +1159,11 @@ Deleting A Child into the subtree will see that the child subdirectories are not modified by this operation. Only the link from the given directory to its child is severed. + In Tahoe-LAFS v1.9.0 and later, t=unlink can be used as a synonym for t=delete. + If interoperability with older web-API servers is required, t=delete should + be used. + + Renaming A Child ---------------- diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 508df92c..908c6b05 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -1093,21 +1093,25 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi r'\s+%d' % len(self.BAR_CONTENTS), ]) self.failUnless(re.search(get_bar, res), res) - for line in res.split("\n"): - # find the line that contains the delete button for bar.txt - if ("form action" in line and - 'value="delete"' in line and - 'value="bar.txt"' in line): - # the form target should use a relative URL - foo_url = urllib.quote("%s/uri/%s/" % (ROOT, self._foo_uri)) - self.failUnless(('action="%s"' % foo_url) in line, line) - # and the when_done= should too - #done_url = urllib.quote(???) - #self.failUnless(('name="when_done" value="%s"' % done_url) - # in line, line) - break - else: - self.fail("unable to find delete-bar.txt line", res) + for label in ['unlink', 'rename']: + for line in res.split("\n"): + # find the line that contains the relevant button for bar.txt + if ("form action" in line and + ('value="%s"' % (label,)) in line and + 'value="bar.txt"' in line): + # the form target should use a relative URL + foo_url = urllib.quote("%s/uri/%s/" % (ROOT, self._foo_uri)) + self.failUnlessIn('action="%s"' % foo_url, line) + # and the when_done= should too + #done_url = urllib.quote(???) + #self.failUnlessIn('name="when_done" value="%s"' % done_url, line) + + # 'unlink' needs to use POST because it directly has a side effect + if label == 'unlink': + self.failUnlessIn('method="post"', line) + break + else: + self.fail("unable to find '%s bar.txt' line" % (label,), res) # the DIR reference just points to a URI sub_url = ("%s/uri/%s/" % (ROOT, urllib.quote(self._sub_uri))) @@ -2638,14 +2642,21 @@ class Web(WebMixin, WebErrorMixin, testutil.StallMixin, testutil.ReallyEqualMixi d.addCallback(self.failUnlessIsBarDotTxt) return d - def test_POST_delete(self): - d = self.POST(self.public_url + "/foo", t="delete", name="bar.txt") + def test_POST_delete(self, command_name='delete'): + d = self._foo_node.list() + def _check_before(children): + self.failUnless(u"bar.txt" in children) + d.addCallback(_check_before) + d.addCallback(lambda res: self.POST(self.public_url + "/foo", t=command_name, name="bar.txt")) d.addCallback(lambda res: self._foo_node.list()) - def _check(children): + def _check_after(children): self.failIf(u"bar.txt" in children) - d.addCallback(_check) + d.addCallback(_check_after) return d + def test_POST_unlink(self): + return self.test_POST_delete(command_name='unlink') + def test_POST_rename_file(self): d = self.POST(self.public_url + "/foo", t="rename", from_name="bar.txt", to_name='wibble.txt') diff --git a/src/allmydata/web/directory.py b/src/allmydata/web/directory.py index c04c74a1..c4e6fae8 100644 --- a/src/allmydata/web/directory.py +++ b/src/allmydata/web/directory.py @@ -202,8 +202,8 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): d = self._POST_upload(ctx) # this one needs the context elif t == "uri": d = self._POST_uri(req) - elif t == "delete": - d = self._POST_delete(req) + elif t == "delete" or t == "unlink": + d = self._POST_unlink(req) elif t == "rename": d = self._POST_rename(req) elif t == "check": @@ -361,22 +361,22 @@ class DirectoryNodeHandler(RenderMixin, rend.Page, ReplaceMeMixin): d.addCallback(lambda res: childcap) return d - def _POST_delete(self, req): + def _POST_unlink(self, req): name = get_arg(req, "name") if name is None: # apparently an # won't show up in the resulting encoded form.. the 'name' - # field is completely missing. So to allow deletion of an - # empty file, we have to pretend that None means ''. The only - # downside of this is a slightly confusing error message if - # someone does a POST without a name= field. For our own HTML - # this isn't a big deal, because we create the 'delete' POST - # buttons ourselves. + # field is completely missing. So to allow unlinking of a + # child with a name that is the empty string, we have to + # pretend that None means ''. The only downside of this is + # a slightly confusing error message if someone does a POST + # without a name= field. For our own HTML this isn't a big + # deal, because we create the 'unlink' POST buttons ourselves. name = '' charset = get_arg(req, "_charset", "utf-8") name = name.decode(charset) d = self.node.delete(name) - d.addCallback(lambda res: "thing deleted") + d.addCallback(lambda res: "thing unlinked") return d def _POST_rename(self, req): @@ -644,17 +644,17 @@ class DirectoryAsHTML(rend.Page): root = get_root(ctx) here = "%s/uri/%s/" % (root, urllib.quote(self.node.get_uri())) if self.node.is_unknown() or self.node.is_readonly(): - delete = "-" + unlink = "-" rename = "-" else: - # this creates a button which will cause our child__delete method - # to be invoked, which deletes the file and then redirects the + # this creates a button which will cause our _POST_unlink method + # to be invoked, which unlinks the file and then redirects the # browser back to this directory - delete = T.form(action=here, method="post")[ - T.input(type='hidden', name='t', value='delete'), + unlink = T.form(action=here, method="post")[ + T.input(type='hidden', name='t', value='unlink'), T.input(type='hidden', name='name', value=name), T.input(type='hidden', name='when_done', value="."), - T.input(type='submit', value='del', name="del"), + T.input(type='submit', value='unlink', name="unlink"), ] rename = T.form(action=here, method="get")[ @@ -664,7 +664,7 @@ class DirectoryAsHTML(rend.Page): T.input(type='submit', value='rename', name="rename"), ] - ctx.fillSlots("delete", delete) + ctx.fillSlots("unlink", unlink) ctx.fillSlots("rename", rename) times = [] diff --git a/src/allmydata/web/directory.xhtml b/src/allmydata/web/directory.xhtml index a6329219..4875738d 100644 --- a/src/allmydata/web/directory.xhtml +++ b/src/allmydata/web/directory.xhtml @@ -31,7 +31,7 @@ - +