2 import os.path, re, sys
3 from twisted.python import usage
4 from allmydata.scripts.common import BaseOptions
6 NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
8 class VDriveOptions(BaseOptions, usage.Options):
10 ["node-directory", "d", "~/.tahoe",
11 "Look here to find out which Tahoe node should be used for all "
12 "operations. The directory should either contain a full Tahoe node, "
13 "or a file named node.url which points to some other Tahoe node. "
14 "It should also contain a file named root_dir.cap which contains "
15 "the root dirnode URI that should be used."
17 ["node-url", "u", None,
18 "URL of the tahoe node to use, a URL like \"http://127.0.0.1:8123\". "
19 "This overrides the URL found in the --node-directory ."],
20 ["dir-uri", "r", "root",
21 "Which dirnode URI should be used as a root directory. The "
22 "string 'root' is special, and means we should use the "
23 "directory found in the 'root_dir.cap' file in the 'private' "
24 "subdirectory of the --node-directory ."],
27 def postOptions(self):
28 # compute a node-url from the existing options, put in self['node-url']
29 if self['node-directory']:
30 self['node-directory'] = os.path.expanduser(self['node-directory'])
32 if (not isinstance(self['node-url'], basestring)
33 or not NODEURL_RE.match(self['node-url'])):
34 msg = ("--node-url is required to be a string and look like "
35 "\"http://HOSTNAMEORADDR:PORT\", not: %r" %
37 raise usage.UsageError(msg)
39 node_url_file = os.path.join(self['node-directory'], "node.url")
40 self['node-url'] = open(node_url_file, "r").read().strip()
42 # also compute self['dir-uri']
43 if self['dir-uri'] == "root":
44 uri_file = os.path.join(self['node-directory'], "root_dir.cap")
45 self['dir-uri'] = open(uri_file, "r").read().strip()
46 from allmydata import uri
47 parsed = uri.NewDirectoryURI.init_from_human_encoding(self['dir-uri'])
48 if not uri.IDirnodeURI.providedBy(parsed):
49 raise usage.UsageError("--dir-uri must be a dir URI, or 'root'")
52 class ListOptions(VDriveOptions):
53 def parseArgs(self, vdrive_pathname=""):
54 self['vdrive_pathname'] = vdrive_pathname
56 longdesc = """List the contents of some portion of the virtual drive."""
58 class GetOptions(VDriveOptions):
59 def parseArgs(self, vdrive_filename, local_filename="-"):
60 self['vdrive_filename'] = vdrive_filename
61 self['local_filename'] = local_filename
63 def getSynopsis(self):
64 return "%s get VDRIVE_FILE LOCAL_FILE" % (os.path.basename(sys.argv[0]),)
66 longdesc = """Retrieve a file from the virtual drive and write it to the
67 local filesystem. If LOCAL_FILE is omitted or '-', the contents of the file
68 will be written to stdout."""
70 class PutOptions(VDriveOptions):
71 def parseArgs(self, local_filename, vdrive_filename):
72 self['local_filename'] = local_filename
73 self['vdrive_filename'] = vdrive_filename
75 def getSynopsis(self):
76 return "%s put LOCAL_FILE VDRIVE_FILE" % (os.path.basename(sys.argv[0]),)
78 longdesc = """Put a file into the virtual drive (copying the file's
79 contents from the local filesystem). LOCAL_FILE is required to be a
80 local file (it can't be stdin)."""
82 class RmOptions(VDriveOptions):
83 def parseArgs(self, vdrive_pathname):
84 self['vdrive_pathname'] = vdrive_pathname
86 def getSynopsis(self):
87 return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
89 class MvOptions(VDriveOptions):
90 def parseArgs(self, frompath, topath):
91 self['from'] = frompath
94 def getSynopsis(self):
95 return "%s mv FROM TO" % (os.path.basename(sys.argv[0]),)
99 ["ls", None, ListOptions, "List a directory"],
100 ["get", None, GetOptions, "Retrieve a file from the virtual drive."],
101 ["put", None, PutOptions, "Upload a file into the virtual drive."],
102 ["rm", None, RmOptions, "Unlink a file or directory in the virtual drive."],
103 ["mv", None, MvOptions, "Move a file within the virtual drive."],
106 def list(config, stdout, stderr):
107 from allmydata.scripts import tahoe_ls
108 rc = tahoe_ls.list(config['node-url'],
110 config['vdrive_pathname'],
114 def get(config, stdout, stderr):
115 from allmydata.scripts import tahoe_get
116 vdrive_filename = config['vdrive_filename']
117 local_filename = config['local_filename']
118 rc = tahoe_get.get(config['node-url'],
124 if local_filename is None or local_filename == "-":
125 # be quiet, since the file being written to stdout should be
126 # proof enough that it worked, unless the user is unlucky
127 # enough to have picked an empty file
130 print >>stderr, "%s retrieved and written to %s" % \
131 (vdrive_filename, local_filename)
134 def put(config, stdout, stderr):
135 from allmydata.scripts import tahoe_put
136 vdrive_filename = config['vdrive_filename']
137 local_filename = config['local_filename']
142 rc = tahoe_put.put(config['node-url'],
150 def rm(config, stdout, stderr):
151 from allmydata.scripts import tahoe_rm
152 vdrive_pathname = config['vdrive_pathname']
157 rc = tahoe_rm.rm(config['node-url'],
164 def mv(config, stdout, stderr):
165 from allmydata.scripts import tahoe_mv
166 frompath = config['from']
167 topath = config['to']
168 rc = tahoe_mv.mv(config['node-url'],