def getSynopsis(self):
return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
+class MvOptions(VDriveOptions):
+ def parseArgs(self, frompath, topath):
+ self['from'] = frompath
+ self['to'] = topath
+
+ def getSynopsis(self):
+ return "%s mv FROM TO" % (os.path.basename(sys.argv[0]),)
+
subCommands = [
["ls", None, ListOptions, "List a directory"],
["get", None, GetOptions, "Retrieve a file from the virtual drive."],
["put", None, PutOptions, "Upload a file into the virtual drive."],
["rm", None, RmOptions, "Unlink a file or directory in the virtual drive."],
+ ["mv", None, MvOptions, "Move a file within the virtual drive."],
]
def list(config, stdout, stderr):
stdout, stderr)
return rc
+def mv(config, stdout, stderr):
+ from allmydata.scripts import tahoe_mv
+ frompath = config['from']
+ topath = config['to']
+ rc = tahoe_mv.mv(config['node-url'],
+ config['root-uri'],
+ frompath,
+ topath,
+ stdout, stderr)
+ return rc
+
dispatch = {
"ls": list,
"get": get,
"put": put,
"rm": rm,
+ "mv": mv,
}
--- /dev/null
+#! /usr/bin/python
+
+import re
+import urllib, httplib
+import urlparse
+import simplejson
+
+# copied from twisted/web/client.py
+def _parse(url, defaultPort=None):
+ url = url.strip()
+ parsed = urlparse.urlparse(url)
+ scheme = parsed[0]
+ path = urlparse.urlunparse(('','')+parsed[2:])
+ if defaultPort is None:
+ if scheme == 'https':
+ defaultPort = 443
+ else:
+ defaultPort = 80
+ host, port = parsed[1], defaultPort
+ if ':' in host:
+ host, port = host.split(':')
+ port = int(port)
+ if path == "":
+ path = "/"
+ return scheme, host, port, path
+
+def do_http(method, url, body=""):
+ scheme, host, port, path = _parse(url)
+ if scheme == "http":
+ c = httplib.HTTPConnection(host, port)
+ elif scheme == "https":
+ c = httplib.HTTPSConnection(host, port)
+ else:
+ raise ValueError("unknown scheme '%s', need http or https" % scheme)
+ c.putrequest(method, path)
+ import allmydata
+ c.putheader("User-Agent", "tahoe_mv/%s" % allmydata.__version__)
+ c.putheader("Content-Length", str(len(body)))
+ c.endheaders()
+ c.send(body)
+ return c.getresponse()
+
+def mv(nodeurl, root_uri, frompath, topath, stdout, stderr):
+ if nodeurl[-1] != "/":
+ nodeurl += "/"
+ url = nodeurl + "uri/%s/" % urllib.quote(root_uri.replace("/","!"))
+ data = urllib.urlopen(url + frompath + "?t=json").read()
+
+ nodetype, attrs = simplejson.loads(data)
+ uri = attrs.get("rw_uri") or attrs["ro_uri"]
+
+ put_url = url + topath + "?t=uri"
+ resp = do_http("PUT", put_url, uri)
+ status = resp.status
+ if not re.search(r'^2\d\d$', str(status)):
+ print >>stderr, "error, got %s %s" % (resp.status, resp.reason)
+ print >>stderr, resp.read()
+
+ # now remove the original
+ resp = do_http("DELETE", url + frompath)
+ if not re.search(r'^2\d\d$', str(status)):
+ print >>stderr, "error, got %s %s" % (resp.status, resp.reason)
+ print >>stderr, resp.read()
+
+ print >>stdout, "OK"
+ return
+
+
+
self.failUnlessEqual(err, "")
d.addCallback(_check_get)
+ def _mv(res):
+ argv = ["mv"] + nodeargs + ["test_put/upload.txt",
+ "test_put/moved.txt"]
+ return self._run_cli(argv)
+ d.addCallback(_mv)
+ def _check_mv((out,err)):
+ self.failUnless("OK" in out)
+ self.failUnlessEqual(err, "")
+ vdrive0 = self.clients[0].getServiceNamed("vdrive")
+ d = defer.maybeDeferred(vdrive0.get_node_at_path,
+ "~/test_put/upload.txt")
+ d.addBoth(self.shouldFail, KeyError, "test_cli._check_rm",
+ "unable to find child named 'upload.txt'")
+ d.addCallback(lambda res:
+ vdrive0.get_node_at_path("~/test_put/moved.txt"))
+ d.addCallback(lambda filenode: filenode.download_to_data())
+ def _check_mv2(res):
+ self.failUnless("I will not write" in res)
+ d.addCallback(_check_mv2)
+ return d
+ d.addCallback(_check_mv)
+
def _rm(res):
- argv = ["rm"] + nodeargs + ["test_put/upload.txt"]
+ argv = ["rm"] + nodeargs + ["test_put/moved.txt"]
return self._run_cli(argv)
d.addCallback(_rm)
def _check_rm((out,err)):
self.failUnlessEqual(err, "")
vdrive0 = self.clients[0].getServiceNamed("vdrive")
d = defer.maybeDeferred(vdrive0.get_node_at_path,
- "~/test_put/upload.txt")
+ "~/test_put/moved.txt")
d.addBoth(self.shouldFail, KeyError, "test_cli._check_rm",
- "unable to find child named 'upload.txt'")
+ "unable to find child named 'moved.txt'")
return d
d.addCallback(_check_rm)
return d