source file: /home/buildslave/tahoe/edgy/build/src/allmydata/scripts/cli.py
file stats: 157 lines, 139 executed: 88.5% covered
   1. 
   2. import os.path, re, sys
   3. from twisted.python import usage
   4. from allmydata.scripts.common import BaseOptions, get_aliases
   5. 
   6. NODEURL_RE=re.compile("http://([^:]*)(:([1-9][0-9]*))?")
   7. 
   8. class VDriveOptions(BaseOptions, usage.Options):
   9.     optParameters = [
  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 private/aliases which contains "
  15.          "the mapping from alias name to root dirnode URI."
  16.          ],
  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-cap", None, None,
  21.          "Which dirnode URI should be used as the 'tahoe' alias."]
  22.         ]
  23. 
  24.     def postOptions(self):
  25.         # compute a node-url from the existing options, put in self['node-url']
  26.         if self['node-directory']:
  27.             if sys.platform == 'win32' and self['node-directory'] == '~/.tahoe':
  28.                 from allmydata.windows import registry
  29.                 self['node-directory'] = registry.get_base_dir_path()
  30.             else:
  31.                 self['node-directory'] = os.path.expanduser(self['node-directory'])
  32.         if self['node-url']:
  33.             if (not isinstance(self['node-url'], basestring)
  34.                 or not NODEURL_RE.match(self['node-url'])):
  35.                 msg = ("--node-url is required to be a string and look like "
  36.                        "\"http://HOSTNAMEORADDR:PORT\", not: %r" %
  37.                        (self['node-url'],))
  38.                 raise usage.UsageError(msg)
  39.         else:
  40.             node_url_file = os.path.join(self['node-directory'], "node.url")
  41.             self['node-url'] = open(node_url_file, "r").read().strip()
  42. 
  43.         aliases = get_aliases(self['node-directory'])
  44.         if self['dir-cap']:
  45.             aliases["tahoe"] = self['dir-cap']
  46.         self.aliases = aliases # maps alias name to dircap
  47. 
  48. 
  49. class MakeDirectoryOptions(VDriveOptions):
  50.     def parseArgs(self, where=""):
  51.         self.where = where
  52.     longdesc = """Create a new directory, either unlinked or as a subdirectory."""
  53. 
  54. class AddAliasOptions(VDriveOptions):
  55.     def parseArgs(self, alias, cap):
  56.         self.alias = alias
  57.         self.cap = cap
  58. 
  59. class CreateAliasOptions(VDriveOptions):
  60.     def parseArgs(self, alias):
  61.         self.alias = alias
  62. 
  63. class ListAliasOptions(VDriveOptions):
  64.     pass
  65. 
  66. class ListOptions(VDriveOptions):
  67.     optFlags = [
  68.         ("long", "l", "Use long format: show file sizes, and timestamps"),
  69.         ("uri", "u", "Show file/directory URIs"),
  70.         ("readonly-uri", None, "Show readonly file/directory URIs"),
  71.         ("classify", "F", "Append '/' to directory names, and '*' to mutable"),
  72.         ("json", None, "Show the raw JSON output"),
  73.         ]
  74.     def parseArgs(self, where=""):
  75.         self.where = where
  76. 
  77.     longdesc = """List the contents of some portion of the virtual drive."""
  78. 
  79. class GetOptions(VDriveOptions):
  80.     def parseArgs(self, arg1, arg2=None):
  81.         # tahoe get FOO |less            # write to stdout
  82.         # tahoe get tahoe:FOO |less      # same
  83.         # tahoe get FOO bar              # write to local file
  84.         # tahoe get tahoe:FOO bar        # same
  85. 
  86.         self.from_file = arg1
  87.         self.to_file = arg2
  88.         if self.to_file == "-":
  89.             self.to_file = None
  90. 
  91.     def getSynopsis(self):
  92.         return "%s get VDRIVE_FILE LOCAL_FILE" % (os.path.basename(sys.argv[0]),)
  93. 
  94.     longdesc = """Retrieve a file from the virtual drive and write it to the
  95.     local filesystem. If LOCAL_FILE is omitted or '-', the contents of the file
  96.     will be written to stdout."""
  97. 
  98.     def getUsage(self, width=None):
  99.         t = VDriveOptions.getUsage(self, width)
 100.         t += """
 101. Examples:
 102.  % tahoe get FOO |less            # write to stdout
 103.  % tahoe get tahoe:FOO |less      # same
 104.  % tahoe get FOO bar              # write to local file
 105.  % tahoe get tahoe:FOO bar        # same
 106. """
 107.         return t
 108. 
 109. class PutOptions(VDriveOptions):
 110.     optFlags = [
 111.         ("mutable", "m", "Create a mutable file instead of an immutable one."),
 112.         ]
 113. 
 114.     def parseArgs(self, arg1=None, arg2=None):
 115.         # cat FILE > tahoe put           # create unlinked file from stdin
 116.         # cat FILE > tahoe put -         # same
 117.         # tahoe put bar                  # create unlinked file from local 'bar'
 118.         # cat FILE > tahoe put - FOO     # create tahoe:FOO from stdin
 119.         # tahoe put bar FOO              # copy local 'bar' to tahoe:FOO
 120.         # tahoe put bar tahoe:FOO        # same
 121. 
 122.         if arg1 is not None and arg2 is not None:
 123.             self.from_file = arg1
 124.             self.to_file = arg2
 125.         elif arg1 is not None and arg2 is None:
 126.             self.from_file = arg1 # might be "-"
 127.             self.to_file = None
 128.         else:
 129.             self.from_file = None
 130.             self.to_file = None
 131.         if self.from_file == "-":
 132.             self.from_file = None
 133. 
 134.     def getSynopsis(self):
 135.         return "%s put LOCAL_FILE VDRIVE_FILE" % (os.path.basename(sys.argv[0]),)
 136. 
 137.     longdesc = """Put a file into the virtual drive (copying the file's
 138.     contents from the local filesystem). If VDRIVE_FILE is missing, upload
 139.     the file but do not link it into a directory: prints the new filecap to
 140.     stdout. If LOCAL_FILE is missing or '-', data will be copied from stdin.
 141.     VDRIVE_FILE is assumed to start with tahoe: unless otherwise specified."""
 142. 
 143.     def getUsage(self, width=None):
 144.         t = VDriveOptions.getUsage(self, width)
 145.         t += """
 146. Examples:
 147.  % cat FILE > tahoe put                # create unlinked file from stdin
 148.  % cat FILE > tahoe -                  # same
 149.  % tahoe put bar                       # create unlinked file from local 'bar'
 150.  % cat FILE > tahoe put - FOO          # create tahoe:FOO from stdin
 151.  % tahoe put bar FOO                   # copy local 'bar' to tahoe:FOO
 152.  % tahoe put bar tahoe:FOO             # same
 153.  % tahoe put bar MUTABLE-FILE-WRITECAP # modify the mutable file in-place
 154. """
 155.         return t
 156. 
 157. class CpOptions(VDriveOptions):
 158.     optFlags = [
 159.         ("recursive", "r", "Copy source directory recursively."),
 160.         ("verbose", "v", "Be noisy about what is happening."),
 161.         ]
 162.     def parseArgs(self, *args):
 163.         if len(args) < 2:
 164.             raise usage.UsageError("cp requires at least two arguments")
 165.         self.sources = args[:-1]
 166.         self.destination = args[-1]
 167. 
 168. class RmOptions(VDriveOptions):
 169.     def parseArgs(self, where):
 170.         self.where = where
 171. 
 172.     def getSynopsis(self):
 173.         return "%s rm VE_FILE" % (os.path.basename(sys.argv[0]),)
 174. 
 175. class MvOptions(VDriveOptions):
 176.     def parseArgs(self, frompath, topath):
 177.         self.from_file = frompath
 178.         self.to_file = topath
 179. 
 180.     def getSynopsis(self):
 181.         return "%s mv FROM TO" % (os.path.basename(sys.argv[0]),)
 182. 
 183. class LnOptions(VDriveOptions):
 184.     def parseArgs(self, frompath, topath):
 185.         self.from_file = frompath
 186.         self.to_file = topath
 187. 
 188.     def getSynopsis(self):
 189.         return "%s ln FROM TO" % (os.path.basename(sys.argv[0]),)
 190. 
 191. class WebopenOptions(VDriveOptions):
 192.     def parseArgs(self, where=''):
 193.         self.where = where
 194. 
 195.     def getSynopsis(self):
 196.         return "%s webopen [ALIAS:PATH]" % (os.path.basename(sys.argv[0]),)
 197. 
 198.     longdesc = """Opens a webbrowser to the contents of some portion of the virtual drive."""
 199. 
 200. subCommands = [
 201.     ["mkdir", None, MakeDirectoryOptions, "Create a new directory"],
 202.     ["add-alias", None, AddAliasOptions, "Add a new alias cap"],
 203.     ["create-alias", None, CreateAliasOptions, "Create a new alias cap"],
 204.     ["list-aliases", None, ListAliasOptions, "List all alias caps"],
 205.     ["ls", None, ListOptions, "List a directory"],
 206.     ["get", None, GetOptions, "Retrieve a file from the virtual drive."],
 207.     ["put", None, PutOptions, "Upload a file into the virtual drive."],
 208.     ["cp", None, CpOptions, "Copy one or more files."],
 209.     ["rm", None, RmOptions, "Unlink a file or directory in the virtual drive."],
 210.     ["mv", None, MvOptions, "Move a file within the virtual drive."],
 211.     ["ln", None, LnOptions, "Make an additional link to an existing file."],
 212.     ["webopen", None, WebopenOptions, "Open a webbrowser to the root_dir"],
 213.     ]
 214. 
 215. def mkdir(options):
 216.     from allmydata.scripts import tahoe_mkdir
 217.     rc = tahoe_mkdir.mkdir(options)
 218.     return rc
 219. 
 220. def add_alias(options):
 221.     from allmydata.scripts import tahoe_add_alias
 222.     rc = tahoe_add_alias.add_alias(options)
 223.     return rc
 224. 
 225. def create_alias(options):
 226.     from allmydata.scripts import tahoe_add_alias
 227.     rc = tahoe_add_alias.create_alias(options)
 228.     return rc
 229. 
 230. def list_aliases(options):
 231.     from allmydata.scripts import tahoe_add_alias
 232.     rc = tahoe_add_alias.list_aliases(options)
 233.     return rc
 234. 
 235. def list(options):
 236.     from allmydata.scripts import tahoe_ls
 237.     rc = tahoe_ls.list(options)
 238.     return rc
 239. 
 240. def get(options):
 241.     from allmydata.scripts import tahoe_get
 242.     rc = tahoe_get.get(options)
 243.     if rc == 0:
 244.         if options.to_file is None:
 245.             # be quiet, since the file being written to stdout should be
 246.             # proof enough that it worked, unless the user is unlucky
 247.             # enough to have picked an empty file
 248.             pass
 249.         else:
 250.             print >>options.stderr, "%s retrieved and written to %s" % \
 251.                   (options.from_file, options.to_file)
 252.     return rc
 253. 
 254. def put(options):
 255.     from allmydata.scripts import tahoe_put
 256.     rc = tahoe_put.put(options)
 257.     return rc
 258. 
 259. def cp(options):
 260.     from allmydata.scripts import tahoe_cp
 261.     rc = tahoe_cp.copy(options)
 262.     return rc
 263. 
 264. def rm(options):
 265.     from allmydata.scripts import tahoe_rm
 266.     rc = tahoe_rm.rm(options)
 267.     return rc
 268. 
 269. def mv(options):
 270.     from allmydata.scripts import tahoe_mv
 271.     rc = tahoe_mv.mv(options, mode="move")
 272.     return rc
 273. 
 274. def ln(options):
 275.     from allmydata.scripts import tahoe_mv
 276.     rc = tahoe_mv.mv(options, mode="link")
 277.     return rc
 278. 
 279. def webopen(options, opener=None):
 280.     from allmydata.scripts import tahoe_webopen
 281.     rc = tahoe_webopen.webopen(options, opener=opener)
 282.     return rc
 283. 
 284. dispatch = {
 285.     "mkdir": mkdir,
 286.     "add-alias": add_alias,
 287.     "create-alias": create_alias,
 288.     "list-aliases": list_aliases,
 289.     "ls": list,
 290.     "get": get,
 291.     "put": put,
 292.     "cp": cp,
 293.     "rm": rm,
 294.     "mv": mv,
 295.     "ln": ln,
 296.     "webopen": webopen,
 297.     }
 298.