mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-06-20 00:03:58 +00:00
command-line: add "rm", and tidy-up variable names, and make it so "allmydata-tahoe spam" prints a usage message instead of returning silently
This commit is contained in:
@ -104,10 +104,11 @@ available there, with download links, and forms to upload new files.
|
|||||||
|
|
||||||
USAGE - command-line interface
|
USAGE - command-line interface
|
||||||
|
|
||||||
Run "allmydata-tahoe ls [VIRTUAL DIRECTORY NAME]" to list the contents
|
Run "allmydata-tahoe ls [VIRTUAL PATH NAME]" to list the contents of a
|
||||||
of a virtual directory. Run "allmydata-tahoe get [VIRTUAL FILE NAME]
|
virtual directory. Run "allmydata-tahoe get [VIRTUAL FILE NAME] [LOCAL FILE
|
||||||
[LOCAL FILE NAME]" to download a file. Run "allmydata-tahoe put
|
NAME]" to download a file. Run "allmydata-tahoe put [LOCAL FILE NAME]
|
||||||
[LOCAL FILE NAME] [VIRTUAL FILE NAME]" to upload a file.
|
[VIRTUAL FILE NAME]" to upload a file. Run "allmydata-tahoe rm [VIRTUAL PATH
|
||||||
|
NAME]" to unlink a file or directory in the virtual drive.
|
||||||
|
|
||||||
USAGE - other
|
USAGE - other
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@ class VDriveOptions(BaseOptions, usage.Options):
|
|||||||
raise usage.UsageError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (self['node-url'],))
|
raise usage.UsageError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (self['node-url'],))
|
||||||
|
|
||||||
class ListOptions(VDriveOptions):
|
class ListOptions(VDriveOptions):
|
||||||
def parseArgs(self, vdrive_filename=""):
|
def parseArgs(self, vdrive_pathname=""):
|
||||||
self['vdrive_filename'] = vdrive_filename
|
self['vdrive_pathname'] = vdrive_pathname
|
||||||
|
|
||||||
longdesc = """List the contents of some portion of the virtual drive."""
|
longdesc = """List the contents of some portion of the virtual drive."""
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ class GetOptions(VDriveOptions):
|
|||||||
|
|
||||||
class PutOptions(VDriveOptions):
|
class PutOptions(VDriveOptions):
|
||||||
def parseArgs(self, local_filename, vdrive_filename):
|
def parseArgs(self, local_filename, vdrive_filename):
|
||||||
self['vdrive_filename'] = vdrive_filename
|
|
||||||
self['local_filename'] = local_filename
|
self['local_filename'] = local_filename
|
||||||
|
self['vdrive_filename'] = vdrive_filename
|
||||||
|
|
||||||
def getSynopsis(self):
|
def getSynopsis(self):
|
||||||
return "%s put LOCAL_FILEVDRI VE_FILE" % (os.path.basename(sys.argv[0]),)
|
return "%s put LOCAL_FILEVDRI VE_FILE" % (os.path.basename(sys.argv[0]),)
|
||||||
@ -48,19 +48,26 @@ class PutOptions(VDriveOptions):
|
|||||||
contents from the local filesystem). If LOCAL_FILE is omitted or '-', the
|
contents from the local filesystem). If LOCAL_FILE is omitted or '-', the
|
||||||
contents of the file will be read from stdin."""
|
contents of the file will be read from stdin."""
|
||||||
|
|
||||||
|
class RmOptions(VDriveOptions):
|
||||||
|
def parseArgs(self, vdrive_pathname):
|
||||||
|
self['vdrive_pathname'] = vdrive_pathname
|
||||||
|
|
||||||
|
def getSynopsis(self):
|
||||||
|
return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
|
||||||
|
|
||||||
|
|
||||||
subCommands = [
|
subCommands = [
|
||||||
["ls", None, ListOptions, "List a directory"],
|
["ls", None, ListOptions, "List a directory"],
|
||||||
["get", None, GetOptions, "Retrieve a file from the virtual drive."],
|
["get", None, GetOptions, "Retrieve a file from the virtual drive."],
|
||||||
["put", None, PutOptions, "Upload a file into 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."],
|
||||||
]
|
]
|
||||||
|
|
||||||
def list(config, stdout, stderr):
|
def list(config, stdout, stderr):
|
||||||
from allmydata.scripts import tahoe_ls
|
from allmydata.scripts import tahoe_ls
|
||||||
rc = tahoe_ls.list(config['node-url'],
|
rc = tahoe_ls.list(config['node-url'],
|
||||||
config['vdrive'],
|
config['vdrive'],
|
||||||
config['vdrive_filename'])
|
config['vdrive_pathname'])
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
def get(config, stdout, stderr):
|
def get(config, stdout, stderr):
|
||||||
@ -92,8 +99,21 @@ def put(config, stdout, stderr):
|
|||||||
verbosity = 2
|
verbosity = 2
|
||||||
rc = tahoe_put.put(config['node-url'],
|
rc = tahoe_put.put(config['node-url'],
|
||||||
config['vdrive'],
|
config['vdrive'],
|
||||||
vdrive_filename,
|
|
||||||
local_filename,
|
local_filename,
|
||||||
|
vdrive_filename,
|
||||||
|
verbosity)
|
||||||
|
return rc
|
||||||
|
|
||||||
|
def rm(config, stdout, stderr):
|
||||||
|
from allmydata.scripts import tahoe_rm
|
||||||
|
vdrive_pathname = config['vdrive_pathname']
|
||||||
|
if config['quiet']:
|
||||||
|
verbosity = 0
|
||||||
|
else:
|
||||||
|
verbosity = 2
|
||||||
|
rc = tahoe_rm.rm(config['node-url'],
|
||||||
|
config['vdrive'],
|
||||||
|
vdrive_pathname,
|
||||||
verbosity)
|
verbosity)
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
@ -101,5 +121,6 @@ dispatch = {
|
|||||||
"ls": list,
|
"ls": list,
|
||||||
"get": get,
|
"get": get,
|
||||||
"put": put,
|
"put": put,
|
||||||
|
"rm": rm,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ def runner(argv, run_by_human=True, stdout=sys.stdout, stderr=sys.stderr):
|
|||||||
rc = debug.dispatch[command](so, stdout, stderr)
|
rc = debug.dispatch[command](so, stdout, stderr)
|
||||||
elif command in cli.dispatch:
|
elif command in cli.dispatch:
|
||||||
rc = cli.dispatch[command](so, stdout, stderr)
|
rc = cli.dispatch[command](so, stdout, stderr)
|
||||||
|
else:
|
||||||
|
raise usage.UsageError()
|
||||||
|
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
import sys, urllib
|
import sys, urllib
|
||||||
|
|
||||||
def get(nodeurl, vdrive, vdrive_file, local_file):
|
def get(nodeurl, vdrive, vdrive_fname, local_file):
|
||||||
if nodeurl[-1] != "/":
|
if nodeurl[-1] != "/":
|
||||||
nodeurl += "/"
|
nodeurl += "/"
|
||||||
url = nodeurl + "vdrive/" + vdrive + "/"
|
url = nodeurl + "vdrive/" + vdrive + "/"
|
||||||
if vdrive_file:
|
if vdrive_fname:
|
||||||
url += vdrive_file
|
url += vdrive_fname
|
||||||
|
|
||||||
if local_file is None or local_file == "-":
|
if local_file is None or local_file == "-":
|
||||||
outf = sys.stdout
|
outf = sys.stdout
|
||||||
@ -36,12 +36,12 @@ def main():
|
|||||||
if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
|
if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
|
||||||
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
||||||
|
|
||||||
vdrive_file = args[0]
|
vdrive_fname = args[0]
|
||||||
local_file = None
|
local_file = None
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
local_file = args[1]
|
local_file = args[1]
|
||||||
|
|
||||||
get(options.nodeurl, options.vdrive, vdrive_file, local_file)
|
get(options.nodeurl, options.vdrive, vdrive_fname, local_file)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
import urllib
|
import urllib
|
||||||
import simplejson
|
import simplejson
|
||||||
|
|
||||||
def list(nodeurl, vdrive, vdrive_file):
|
def list(nodeurl, vdrive, vdrive_pathname):
|
||||||
if nodeurl[-1] != "/":
|
if nodeurl[-1] != "/":
|
||||||
nodeurl += "/"
|
nodeurl += "/"
|
||||||
url = nodeurl + "vdrive/" + vdrive + "/"
|
url = nodeurl + "vdrive/" + vdrive + "/"
|
||||||
if vdrive_file:
|
if vdrive_pathname:
|
||||||
url += vdrive_file
|
url += vdrive_pathname
|
||||||
url += "?t=json"
|
url += "?t=json"
|
||||||
data = urllib.urlopen(url).read()
|
data = urllib.urlopen(url).read()
|
||||||
|
|
||||||
@ -40,11 +40,11 @@ def main():
|
|||||||
if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
|
if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
|
||||||
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
||||||
|
|
||||||
vdrive_file = ""
|
vdrive_pathname = ""
|
||||||
if args:
|
if args:
|
||||||
vdrive_file = args[0]
|
vdrive_pathname = args[0]
|
||||||
|
|
||||||
list(options.nodeurl, options.vdrive, vdrive_file)
|
list(options.nodeurl, options.vdrive, vdrive_pathname)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -4,7 +4,7 @@ import re, socket, sys
|
|||||||
|
|
||||||
NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
|
NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
|
||||||
|
|
||||||
def put(nodeurl, vdrive, vdrive_fname, local_fname, verbosity):
|
def put(nodeurl, vdrive, local_fname, vdrive_fname, verbosity):
|
||||||
"""
|
"""
|
||||||
@param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
|
@param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
|
||||||
|
|
||||||
@ -85,11 +85,11 @@ def main():
|
|||||||
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
||||||
|
|
||||||
local_file = args[0]
|
local_file = args[0]
|
||||||
vdrive_file = None
|
vdrive_fname = None
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
vdrive_file = args[1]
|
vdrive_fname = args[1]
|
||||||
|
|
||||||
return put(options.nodeurl, options.vdrive, vdrive_file, local_file)
|
return put(options.nodeurl, options.vdrive, vdrive_fname, local_file)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
77
src/allmydata/scripts/tahoe_rm.py
Normal file
77
src/allmydata/scripts/tahoe_rm.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import re, socket, sys
|
||||||
|
|
||||||
|
NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
|
||||||
|
|
||||||
|
def rm(nodeurl, vdrive, vdrive_pathname, verbosity):
|
||||||
|
"""
|
||||||
|
@param verbosity: 0, 1, or 2, meaning quiet, verbose, or very verbose
|
||||||
|
|
||||||
|
@return: a Deferred which eventually fires with the exit code
|
||||||
|
"""
|
||||||
|
mo = NODEURL_RE.match(nodeurl)
|
||||||
|
host = mo.group(1)
|
||||||
|
port = int(mo.group(3))
|
||||||
|
|
||||||
|
url = "/vdrive/" + vdrive + "/"
|
||||||
|
if vdrive_pathname:
|
||||||
|
url += vdrive_pathname
|
||||||
|
|
||||||
|
so = socket.socket()
|
||||||
|
so.connect((host, port,))
|
||||||
|
|
||||||
|
CHUNKSIZE=2**16
|
||||||
|
data = "DELETE %s HTTP/1.1\r\nConnection: close\r\nHostname: %s\r\n\r\n" % (url, host,)
|
||||||
|
sent = so.send(data)
|
||||||
|
|
||||||
|
respbuf = []
|
||||||
|
data = so.recv(CHUNKSIZE)
|
||||||
|
while data:
|
||||||
|
respbuf.append(data)
|
||||||
|
data = so.recv(CHUNKSIZE)
|
||||||
|
|
||||||
|
so.shutdown(socket.SHUT_WR)
|
||||||
|
|
||||||
|
data = so.recv(CHUNKSIZE)
|
||||||
|
while data:
|
||||||
|
respbuf.append(data)
|
||||||
|
data = so.recv(CHUNKSIZE)
|
||||||
|
|
||||||
|
respstr = ''.join(respbuf)
|
||||||
|
|
||||||
|
headerend = respstr.find('\r\n\r\n')
|
||||||
|
if headerend == -1:
|
||||||
|
headerend = len(respstr)
|
||||||
|
header = respstr[:headerend]
|
||||||
|
RESP_RE=re.compile("^HTTP/[0-9]\.[0-9] ([0-9]*) *([A-Za-z_ ]*)") # This regex is soooo ad hoc... --Zooko 2007-08-16
|
||||||
|
mo = RESP_RE.match(header)
|
||||||
|
if mo:
|
||||||
|
code = int(mo.group(1))
|
||||||
|
word = mo.group(2)
|
||||||
|
|
||||||
|
if code == 200:
|
||||||
|
print "%s %s" % (code, word,)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print respstr[headerend:]
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def main():
|
||||||
|
import optparse, re
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option("-d", "--vdrive", dest="vdrive", default="global")
|
||||||
|
parser.add_option("-u", "--node-url", dest="nodeurl")
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
|
||||||
|
if not isinstance(options.nodeurl, basestring) or not NODEURL_RE.match(options.nodeurl):
|
||||||
|
raise ValueError("--node-url is required to be a string and look like \"http://HOSTNAMEORADDR:PORT\", not: %r" % (options.nodeurl,))
|
||||||
|
|
||||||
|
vdrive_pathname = args[0]
|
||||||
|
|
||||||
|
return put(options.nodeurl, options.vdrive, vdrive_pathname, local_file)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Reference in New Issue
Block a user