From 1dfacdc8a6ac3b0c6bc9ac77c5b948360b7e1331 Mon Sep 17 00:00:00 2001
From: Igor Almeida <igor.contato@gmail.com>
Date: Wed, 21 Nov 2012 15:35:23 -0300
Subject: [PATCH] Add a show-caps command to the CLI

This command lists the available capabilities a path you would give to
'tahoe ls' possesses.
---
 src/allmydata/scripts/cli.py            |   16 ++++++++
 src/allmydata/scripts/tahoe_showcaps.py |   62 +++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 0 deletions(-)
 create mode 100644 src/allmydata/scripts/tahoe_showcaps.py

diff --git a/src/allmydata/scripts/cli.py b/src/allmydata/scripts/cli.py
index 6758fe7..d9d7d59 100644
--- a/src/allmydata/scripts/cli.py
+++ b/src/allmydata/scripts/cli.py
@@ -481,6 +481,15 @@ class DeepCheckOptions(VDriveOptions):
     (which must be a directory), like 'tahoe check' but for multiple files.
     Optionally repair any problems found."""
 
+class ShowCapsOptions(VDriveOptions):
+    optFlags = []
+
+    def parseArgs(self, where=""):
+        self.where = argv_to_unicode(where)
+
+    longdesc = """Given an alias, show its capability and the ones that can be
+    derived from it."""
+
 subCommands = [
     ["mkdir", None, MakeDirectoryOptions, "Create a new directory."],
     ["add-alias", None, AddAliasOptions, "Add a new alias cap."],
@@ -500,6 +509,7 @@ subCommands = [
     ["stats", None, StatsOptions, "Print statistics about all files/directories in a subtree."],
     ["check", None, CheckOptions, "Check a single file or directory."],
     ["deep-check", None, DeepCheckOptions, "Check all files/directories reachable from a starting point."],
+    ["show-caps", None, ShowCapsOptions, "Show all caps an alias can give."],
     ]
 
 def mkdir(options):
@@ -599,6 +609,11 @@ def deepcheck(options):
     rc = tahoe_check.deepcheck(options)
     return rc
 
+def showcaps(options):
+    from allmydata.scripts import tahoe_showcaps
+    rc = tahoe_showcaps.show(options)
+    return rc
+
 dispatch = {
     "mkdir": mkdir,
     "add-alias": add_alias,
@@ -618,4 +633,5 @@ dispatch = {
     "stats": stats,
     "check": check,
     "deep-check": deepcheck,
+    "show-caps": showcaps,
     }
diff --git a/src/allmydata/scripts/tahoe_showcaps.py b/src/allmydata/scripts/tahoe_showcaps.py
new file mode 100644
index 0000000..3809203
--- /dev/null
+++ b/src/allmydata/scripts/tahoe_showcaps.py
@@ -0,0 +1,62 @@
+
+import urllib
+import simplejson
+from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
+                                     UnknownAliasError
+from allmydata.scripts.common_http import do_http, format_http_error
+from allmydata.util.encodingutil import quote_output, is_printable_ascii
+
+def show(options):
+    nodeurl = options['node-url']
+    options['json'] = True
+    aliases = options.aliases
+    where = options.where
+    stdout = options.stdout
+    stderr = options.stderr
+
+    if not nodeurl.endswith("/"):
+        nodeurl += "/"
+    if where.endswith("/"):
+        where = where[:-1]
+    try:
+        rootcap, path = get_alias(aliases, where, DEFAULT_ALIAS)
+    except UnknownAliasError, e:
+        e.display(stderr)
+        return 1
+    url = nodeurl + "uri/%s" % urllib.quote(rootcap)
+    if path:
+        # move where.endswith check here?
+        url += "/" + escape_path(path)
+    assert not url.endswith("/")
+    url += "?t=json"
+    resp = do_http("GET", url)
+    if resp.status == 404:
+        print >>stderr, "No such file or directory"
+        return 2
+    if resp.status != 200:
+        print >>stderr, format_http_error("Error during GET", resp)
+        if resp.status == 0:
+            return 3
+        else:
+            return resp.status
+
+    data = resp.read()
+
+    # The webapi server should always output printable ASCII.
+    # XXX is this necessary?
+    if not is_printable_ascii(data):
+        print >>stderr, "The JSON response contained unprintable characters:\n%s" % quote_output(data)
+        return 1
+
+    try:
+        parsed = simplejson.loads(data)
+    except Exception, e:
+        print >>stderr, "error: %s" % quote_output(e.args[0], quotemarks=False)
+        print >>stderr, "Could not parse JSON response:\n%s" % quote_output(data)
+        return 1
+
+    for key in ("rw_uri", "ro_uri", "verify_uri"):
+        if key in parsed[1]:
+            print >>stdout,'{}: {}'.format(key, parsed[1][key])
+
+    return 0
-- 
1.7.5.4