add a 'rename' button to the webish dir view

alongside the 'del' button is now presented a 'rename' button, which takes
the user to a new page, the 't=rename-form' page, which asks ther user for
the new name of the child and ultimately submits a POST request to the dir
for 't=rename' to perform the actual rename i.e. an attach followed by a
delete of children.
This commit is contained in:
robk-org 2007-07-12 16:53:54 -07:00
parent 15c3055176
commit d65d02fa58
4 changed files with 119 additions and 0 deletions

View File

@ -215,6 +215,13 @@ for files and directories which do not yet exist.
curl -T /dev/null 'http://localhost:8011/vdrive/global/newdir?t=upload&localdir=/home/user/directory-to-upload' curl -T /dev/null 'http://localhost:8011/vdrive/global/newdir?t=upload&localdir=/home/user/directory-to-upload'
GET DIRURL?t=rename-form&name=$CHILDNAME
This provides a useful facility to browser-based user interfaces.
It returns a page containing a form targetting the POST DIRURL t=rename
functionality listed below, with the provided $CHILDNAME present in the
'from_name' field of that form. i.e. this presents a form offering to
rename $CHILDNAME, requesting the new name, and submitting POST rename
== POST Forms == == POST Forms ==
@ -252,6 +259,15 @@ for files and directories which do not yet exist.
This instructs the client to delete a file from the given dirnode. The name This instructs the client to delete a file from the given dirnode. The name
of the child to be deleted will be included in the form's arguments. of the child to be deleted will be included in the form's arguments.
POST DIRURL
t=rename
from_name=oldchildname
to_name=newchildname
This instructs the client to rename a child within the given dirnode. The
child specified by 'from_name' is removed, and reattached as a child named
for 'to_name'. This is unconditional and will replace any child already
present under 'to_name', akin to 'mv -f' in unix parlance.
== URI == == URI ==

View File

@ -29,6 +29,7 @@
<td>Size</td> <td>Size</td>
<td>other representations</td> <td>other representations</td>
<td></td> <td></td>
<td></td>
</tr> </tr>
<tr n:pattern="item" n:render="row"> <tr n:pattern="item" n:render="row">
<td><n:slot name="filename"/></td> <td><n:slot name="filename"/></td>
@ -36,6 +37,7 @@
<td><n:slot name="size"/></td> <td><n:slot name="size"/></td>
<td><n:slot name="data"/></td> <td><n:slot name="data"/></td>
<td><n:slot name="delete"/></td> <td><n:slot name="delete"/></td>
<td><n:slot name="rename"/></td>
</tr> </tr>
<tr n:pattern="empty"><td>directory is empty!</td></tr> <tr n:pattern="empty"><td>directory is empty!</td></tr>

View File

@ -0,0 +1,31 @@
<html xmlns:n="http://nevow.com/ns/nevow/0.1">
<head>
<title n:render="title"></title>
<!-- <link href="http://www.allmydata.com/common/css/styles.css"
rel="stylesheet" type="text/css"/> -->
<link href="/webform_css" rel="stylesheet" type="text/css"/>
<link href="/tahoe_css" rel="stylesheet" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h2 n:render="header" />
<div class="freeform-form">
<form action="." method="post" enctype="multipart/form-data">
<fieldset>
<legend class="freeform-form-label">Rename child</legend>
<input type="hidden" name="t" value="rename" />
<input n:render="when_done" />
Rename child:
<input type="text" name="from_name" readonly="true" n:render="get_name" />
to
<input type="text" name="to_name" />
<input type="submit" value="rename" />
</fieldset>
</form>
</div>
</body></html>

View File

@ -80,9 +80,18 @@ class Directory(rend.Page):
T.input(type='hidden', name='when_done', value=url.here), T.input(type='hidden', name='when_done', value=url.here),
T.input(type='submit', value='del', name="del"), T.input(type='submit', value='del', name="del"),
] ]
rename = T.form(action=url.here, method="get")[
T.input(type='hidden', name='t', value='rename-form'),
T.input(type='hidden', name='name', value=name),
T.input(type='hidden', name='when_done', value=url.here),
T.input(type='submit', value='rename', name="rename"),
]
else: else:
delete = "-" delete = "-"
rename = "-"
ctx.fillSlots("delete", delete) ctx.fillSlots("delete", delete)
ctx.fillSlots("rename", rename)
# build the base of the uri_link link url # build the base of the uri_link link url
uri_link = urllib.quote(target.get_uri().replace("/", "!")) uri_link = urllib.quote(target.get_uri().replace("/", "!"))
@ -429,6 +438,46 @@ class DirectoryReadonlyURI(DirectoryJSONMetadata):
def renderNode(self, node): def renderNode(self, node):
return node.get_immutable_uri() return node.get_immutable_uri()
class RenameForm(rend.Page):
addSlash = True
docFactory = getxmlfile("rename-form.xhtml")
def __init__(self, rootname, dirnode, dirpath):
self._rootname = rootname
self._dirnode = dirnode
self._dirpath = dirpath
def dirpath_as_string(self):
return "/" + "/".join(self._dirpath)
def render_title(self, ctx, data):
return ctx.tag["Directory '%s':" % self.dirpath_as_string()]
def render_header(self, ctx, data):
parent_directories = ("<%s>" % self._rootname,) + self._dirpath
num_dirs = len(parent_directories)
header = [ "Rename in directory '",
"<%s>/" % self._rootname,
"/".join(self._dirpath),
"':", ]
if not self._dirnode.is_mutable():
header.append(" (readonly)")
return ctx.tag[header]
def render_when_done(self, ctx, data):
return T.input(type="hidden", name="when_done", value=url.here)
def render_get_name(self, ctx, data):
req = inevow.IRequest(ctx)
if 'name' in req.args:
name = req.args['name'][0]
else:
name = ''
ctx.tag.attributes['value'] = name
return ctx.tag
class POSTHandler(rend.Page): class POSTHandler(rend.Page):
def __init__(self, node): def __init__(self, node):
self._node = node self._node = node
@ -478,6 +527,25 @@ class POSTHandler(rend.Page):
def _done(res): def _done(res):
return "thing deleted" return "thing deleted"
d.addCallback(_done) d.addCallback(_done)
elif t == "rename":
from_name = 'from_name' in req.fields and req.fields["from_name"].value
to_name = 'to_name' in req.fields and req.fields["to_name"].value
if not from_name or not to_name:
raise RuntimeError("rename requires from_name and to_name")
if not IDirectoryNode.providedBy(self._node):
raise RuntimeError("rename must only be called on directories")
d = self._node.get(from_name)
def add_dest(child):
uri = child.get_uri()
# now actually do the rename
return self._node.set_uri(to_name, uri)
d.addCallback(add_dest)
def rm_src(junk):
return self._node.delete(from_name)
d.addCallback(rm_src)
def _done(res):
return "thing renamed"
d.addCallback(_done)
elif t == "upload": elif t == "upload":
contents = req.fields["file"] contents = req.fields["file"]
name = name or contents.filename name = name or contents.filename
@ -744,6 +812,8 @@ class VDrive(rend.Page):
return DirectoryReadonlyURI(node), () return DirectoryReadonlyURI(node), ()
elif t == "manifest": elif t == "manifest":
return Manifest(node, path), () return Manifest(node, path), ()
elif t == 'rename-form':
return RenameForm(self.name, node, path), ()
else: else:
raise RuntimeError("bad t=%s" % t) raise RuntimeError("bad t=%s" % t)
else: else: