manifest: add storage-index strings to the json results
authorBrian Warner <warner@allmydata.com>
Wed, 19 Nov 2008 23:00:27 +0000 (16:00 -0700)
committerBrian Warner <warner@allmydata.com>
Wed, 19 Nov 2008 23:00:27 +0000 (16:00 -0700)
docs/frontends/webapi.txt
src/allmydata/dirnode.py
src/allmydata/interfaces.py
src/allmydata/scripts/cli.py
src/allmydata/test/test_dirnode.py
src/allmydata/test/test_system.py
src/allmydata/test/test_web.py
src/allmydata/web/directory.py

index cfa96ea75a529bcc6a163e4be4818e42cbb7bffe..500fc3d25aa0cb65a410ba4e2780b17e00b570ab 100644 (file)
@@ -964,11 +964,12 @@ POST $DIRURL?t=start-manifest    (must add &ophandle=XYZ)
   by a space.
 
   If output=JSON is added to the queryargs, then the results will be a
-  JSON-formatted dictionary with four keys:
+  JSON-formatted dictionary with five keys:
 
    finished (bool): if False then you must reload the page until True
-   origin_si (str): the storage index of the starting point
+   origin_si (base32 str): the storage index of the starting point
    manifest: list of (path, cap) tuples, where path is a list of strings.
+   storage-index: list of (base32) storage index strings
    stats: a dictionary with the same keys as the t=deep-stats command
           (described below)
 
index 42db6ab23ddbf0567ee132c964ed16169684afbe..a485a24e8eb29efa878f648b77574beae87e52b6 100644 (file)
@@ -565,7 +565,7 @@ class DeepStats:
     def set_monitor(self, monitor):
         self.monitor = monitor
         monitor.origin_si = self.origin.get_storage_index()
-        monitor.set_status(self.stats)
+        monitor.set_status(self.get_results())
 
     def add_node(self, node, childpath):
         if IDirectoryNode.providedBy(node):
@@ -640,14 +640,20 @@ class ManifestWalker(DeepStats):
     def __init__(self, origin):
         DeepStats.__init__(self, origin)
         self.manifest = []
+        self.storage_index_strings = set()
 
     def add_node(self, node, path):
         self.manifest.append( (tuple(path), node.get_uri()) )
+        si = node.get_storage_index()
+        if si:
+            self.storage_index_strings.add(base32.b2a(si))
         return DeepStats.add_node(self, node, path)
 
-    def finish(self):
+    def get_results(self):
+        stats = DeepStats.get_results(self)
         return {"manifest": self.manifest,
-                "stats": self.get_results(),
+                "storage-index": self.storage_index_strings,
+                "stats": stats,
                 }
 
 
index 885b29cbc3d8c050ee32250c179b147c2df7098f..798b4baf8d0a30671e0525d8095a7c2bf2a05d55 100644 (file)
@@ -875,11 +875,18 @@ class IDirectoryNode(IMutableFilesystemNode):
         I also compute deep-stats as described below.
 
         I return a Monitor. The Monitor's results will be a dictionary with
-        two elements. The 'manifest' element is a list of (path, cap) tuples
-        for nodes (directories and files) reachable from this one. 'path'
-        will be a tuple of unicode strings. The origin dirnode will be
-        represented by an empty path tuple. The 'stats' element is a
-        dictionary, the same that is generated by start_deep_stats() below.
+        three elements:
+
+         res['manifest']: a list of (path, cap) tuples for all nodes
+                          (directories and files) reachable from this one.
+                          'path' will be a tuple of unicode strings. The
+                          origin dirnode will be represented by an empty path
+                          tuple.
+         res['storage-index']: a list of (base32) storage index strings,
+                               one for each reachable node. This is a set:
+                               duplicates have been removed.
+         res['stats']: a dictionary, the same that is generated by
+                       start_deep_stats() below.
 
         The Monitor will also have an .origin_si attribute with the (binary)
         storage index of the starting point.
index 6a0d603035e294ca0044087eac34ae34a8fd2f86..c7bdfab7123c435ea78299ea657b2ab2a2b61561 100644 (file)
@@ -200,6 +200,7 @@ class WebopenOptions(VDriveOptions):
 class ManifestOptions(VDriveOptions):
     optFlags = [
         ("storage-index", "s", "Only print storage index strings, not pathname+cap"),
+        ("raw", "r", "Display raw JSON data instead of parsed"),
         ]
     def parseArgs(self, where=''):
         self.where = where
index c838d6dde2c6e15c1b6dcce17990f7897a84626e..3e1c9729d2bd457e2410dde212438f518e8e4e69 100644 (file)
@@ -27,6 +27,7 @@ class Marker:
             nodeuri = nodeuri.to_string()
         self.nodeuri = nodeuri
         si = hashutil.tagged_hash("tag1", nodeuri)[:16]
+        self.storage_index = si
         fp = hashutil.tagged_hash("tag2", nodeuri)
         self.verifieruri = uri.SSKVerifierURI(storage_index=si, fingerprint=fp)
     def get_uri(self):
@@ -35,6 +36,8 @@ class Marker:
         return self.nodeuri
     def get_verifier(self):
         return self.verifieruri
+    def get_storage_index(self):
+        return self.storage_index
 
     def check(self, monitor, verify=False):
         r = CheckerResults("", None)
index 5cbf36c3189b3e28313d598460f5d22861c9f9d5..c46b552d0c63fa3fd55a85959f0eceffe0a577c6 100644 (file)
@@ -2399,6 +2399,7 @@ class DeepCheckWebGood(DeepCheckBase, unittest.TestCase):
                            "--node-directory", basedir,
                            self.root_uri])
         def _check((out,err)):
+            self.failUnlessEqual(err, "")
             lines = [l for l in out.split("\n") if l]
             self.failUnlessEqual(len(lines), 5)
             caps = {}
index 39e59d1bc3ead73a9a18dd89042ac1fff8d8ad60..019049bd8187b08d1ee9db35fb5166fb28207c48 100644 (file)
@@ -940,13 +940,17 @@ class Web(WebMixin, testutil.StallMixin, unittest.TestCase):
             self.failUnless("\nsub/baz.txt URI:CHK:" in manifest)
         d.addCallback(_got_text)
         d.addCallback(getman, "JSON")
-        def _got_json(manifest):
-            data = manifest["manifest"]
+        def _got_json(res):
+            data = res["manifest"]
             got = {}
             for (path_list, cap) in data:
                 got[tuple(path_list)] = cap
             self.failUnlessEqual(got[(u"sub",)], self._sub_uri)
             self.failUnless((u"sub",u"baz.txt") in got)
+            self.failUnless("finished" in res)
+            self.failUnless("origin" in res)
+            self.failUnless("storage-index" in res)
+            self.failUnless("stats" in res)
         d.addCallback(_got_json)
         return d
 
index 968356305e62b0d76a5cd268ba6024e67fa40784..1e3920f849b4091e0b46e6bb00f10b4caa9fd03e 100644 (file)
@@ -732,6 +732,7 @@ class ManifestResults(rend.Page, ReloadMixin):
         inevow.IRequest(ctx).setHeader("content-type", "text/plain")
         m = self.monitor
         status = {"manifest": m.get_status()["manifest"],
+                  "storage-index": list(m.get_status()["storage-index"]),
                   "stats": m.get_status()["stats"],
                   "finished": m.is_finished(),
                   "origin": base32.b2a(m.origin_si),