[tor-commits] [stem/master] Drop Index class

atagar at torproject.org atagar at torproject.org
Sat Aug 17 20:44:27 UTC 2019


commit 1d99faac82d172312c5627618e9d09e72e639f96
Author: Damian Johnson <atagar at torproject.org>
Date:   Tue Jul 9 12:53:38 2019 -0700

    Drop Index class
    
    Nope, on reflection an Index class won't simplify working with it. Everything
    we need is on a per-file level, so generating a files hash is all we need.
---
 stem/descriptor/collector.py                 | 117 +++---
 test/unit/descriptor/collector.py            |  18 +-
 test/unit/descriptor/data/collector_index.py | 594 ++++++++++++++-------------
 3 files changed, 372 insertions(+), 357 deletions(-)

diff --git a/stem/descriptor/collector.py b/stem/descriptor/collector.py
index 135a5d00..1742c596 100644
--- a/stem/descriptor/collector.py
+++ b/stem/descriptor/collector.py
@@ -122,75 +122,6 @@ def _download(url, compression, timeout, retries):
   return stem.util.str_tools._to_unicode(response)
 
 
-class Index(object):
-  """
-  Index of CollecTor's content.
-
-  :var hash files: mapping of paths to thier content
-  """
-
-  def __init__(self, content):
-    self._str_content = content
-    self._hash_content = Index._convert_paths(json.loads(content))
-
-    self.files = Index._get_files(self._hash_content, [])
-
-  def __str__(self):
-    return self._str_content
-
-  def __iter__(self):
-    for k, v in self._hash_content.items():
-      yield k, v
-
-  @staticmethod
-  def _get_files(val, path):
-    """
-    Provies a mapping of paths to files within the index.
-
-    :param dict val: index hash
-    :param list path: path we've transversed into
-
-    :returns: **dict** mapping paths to files
-    """
-
-    files = {}
-
-    if isinstance(val, dict):
-      for k, v in val.items():
-        if k == 'files':
-          for filename, attr in v.items():
-            file_path = '/'.join(path + [filename])
-            files[file_path] = File(file_path, attr.get('size'), attr.get('last_modified'))
-        elif k == 'directories':
-          for filename, attr in v.items():
-            files.update(Index._get_files(attr, path + [filename]))
-
-    return files
-
-  @staticmethod
-  def _convert_paths(val):
-    """
-    Key files and directories off their paths so we can transverse them more
-    efficiently.
-
-    :val dict val: index to convert
-
-    :returns: index with files and directories converted to path-keyed hashes
-    """
-
-    if isinstance(val, dict):
-      return dict([(k, Index._convert_paths(v)) for (k, v) in val.items()])
-    elif isinstance(val, list) and all([isinstance(entry, dict) and 'path' in entry for entry in val]):
-      contents = {}
-
-      for entry in val:
-        contents[entry['path']] = dict((k, Index._convert_paths(v)) for (k, v) in entry.items() if k != 'path')
-
-      return contents
-    else:
-      return val
-
-
 class File(object):
   """
   File within CollecTor.
@@ -225,6 +156,7 @@ class CollecTor(object):
     self.timeout = timeout
 
     self._cached_index = None
+    self._cached_files = None  # {path => file} mappings in the index
     self._cached_index_at = 0
 
     if compression == 'best':
@@ -253,7 +185,52 @@ class CollecTor(object):
 
     if not self._cached_index or time.time() - self._cached_index_at >= REFRESH_INDEX_RATE:
       response = _download(COLLECTOR_URL + 'index/index.json', self.compression, self.timeout, self.retries)
-      self._cached_index = Index(response)
+      self._cached_index = json.loads(response)
       self._cached_index_at = time.time()
 
     return self._cached_index
+
+  def files(self):
+    """
+    Provides files CollecTor presently has.
+
+    :returns: **hash** mapping paths to :class:`~stem.descriptor.collector.File`
+
+    :raises:
+      If unable to retrieve the index this provide...
+
+        * **ValueError** if json is malformed
+        * **IOError** if unable to decompress
+        * **socket.timeout** if our request timed out
+        * **urllib2.URLError** for most request failures
+    """
+
+    if not self._cached_files or time.time() - self._cached_index_at >= REFRESH_INDEX_RATE:
+      self._cached_files = CollecTor._files(self.index(), [])
+
+    return self._cached_files
+
+  @staticmethod
+  def _files(val, path):
+    """
+    Provies a mapping of paths to files within the index.
+
+    :param dict val: index hash
+    :param list path: path we've transversed into
+
+    :returns: **dict** mapping paths to files
+    """
+
+    files = {}
+
+    if isinstance(val, dict):
+      for k, v in val.items():
+        if k == 'files':
+          for attr in v:
+            file_path = '/'.join(path + [attr.get('path')])
+            files[file_path] = File(file_path, attr.get('size'), attr.get('last_modified'))
+        elif k == 'directories':
+          for attr in v:
+            files.update(CollecTor._files(attr, path + [attr.get('path')]))
+
+    return files
diff --git a/test/unit/descriptor/collector.py b/test/unit/descriptor/collector.py
index cc12ee00..3403ee50 100644
--- a/test/unit/descriptor/collector.py
+++ b/test/unit/descriptor/collector.py
@@ -39,7 +39,7 @@ class TestCollector(unittest.TestCase):
     urlopen_mock.return_value = io.BytesIO(MINIMAL_INDEX_JSON)
 
     collector = CollecTor(compression = Compression.PLAINTEXT)
-    self.assertEqual(MINIMAL_INDEX, dict(collector.index()))
+    self.assertEqual(MINIMAL_INDEX, collector.index())
     urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json', timeout = None)
 
   @patch(URL_OPEN)
@@ -52,7 +52,7 @@ class TestCollector(unittest.TestCase):
     urlopen_mock.return_value = io.BytesIO(zlib.compress(MINIMAL_INDEX_JSON))
 
     collector = CollecTor(compression = Compression.GZIP)
-    self.assertEqual(MINIMAL_INDEX, dict(collector.index()))
+    self.assertEqual(MINIMAL_INDEX, collector.index())
     urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.gz', timeout = None)
 
   @patch(URL_OPEN)
@@ -65,7 +65,7 @@ class TestCollector(unittest.TestCase):
     urlopen_mock.return_value = io.BytesIO(bz2.compress(MINIMAL_INDEX_JSON))
 
     collector = CollecTor(compression = Compression.BZ2)
-    self.assertEqual(MINIMAL_INDEX, dict(collector.index()))
+    self.assertEqual(MINIMAL_INDEX, collector.index())
     urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.bz2', timeout = None)
 
   @patch(URL_OPEN)
@@ -78,7 +78,7 @@ class TestCollector(unittest.TestCase):
     urlopen_mock.return_value = io.BytesIO(lzma.compress(MINIMAL_INDEX_JSON))
 
     collector = CollecTor(compression = Compression.LZMA)
-    self.assertEqual(MINIMAL_INDEX, dict(collector.index()))
+    self.assertEqual(MINIMAL_INDEX, collector.index())
     urlopen_mock.assert_called_with('https://collector.torproject.org/index/index.json.lzma', timeout = None)
 
   @patch(URL_OPEN)
@@ -98,7 +98,7 @@ class TestCollector(unittest.TestCase):
   @patch(URL_OPEN, Mock(return_value = io.BytesIO(MINIMAL_INDEX_JSON)))
   def test_index(self):
     collector = CollecTor(compression = Compression.PLAINTEXT)
-    self.assertEqual(MINIMAL_INDEX, dict(collector.index()))
+    self.assertEqual(MINIMAL_INDEX, collector.index())
 
   @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'not json')))
   def test_index_malformed_json(self):
@@ -121,17 +121,17 @@ class TestCollector(unittest.TestCase):
   @patch(URL_OPEN, Mock(return_value = io.BytesIO(EXAMPLE_INDEX_CONTENT)))
   def test_real_index(self):
     collector = CollecTor(compression = Compression.PLAINTEXT)
-    self.assertEqual(EXAMPLE_INDEX, dict(collector.index()))
+    self.assertEqual(EXAMPLE_INDEX, collector.index())
 
   @patch(URL_OPEN, Mock(return_value = io.BytesIO(EXAMPLE_INDEX_CONTENT)))
   def test_contents(self):
     collector = CollecTor(compression = Compression.PLAINTEXT)
-    index = collector.index()
+    files = collector.files()
 
-    self.assertEqual(85, len(index.files))
+    self.assertEqual(85, len(files))
     test_path = 'archive/relay-descriptors/extra-infos/extra-infos-2007-09.tar.xz'
 
-    extrainfo_file = index.files[test_path]
+    extrainfo_file = files[test_path]
     self.assertEqual(test_path, extrainfo_file.path)
     self.assertEqual(6459884, extrainfo_file.size)
     self.assertEqual(datetime.datetime(2016, 6, 23, 9, 54), extrainfo_file.last_modified)
diff --git a/test/unit/descriptor/data/collector_index.py b/test/unit/descriptor/data/collector_index.py
index b44417af..41ef6cbd 100644
--- a/test/unit/descriptor/data/collector_index.py
+++ b/test/unit/descriptor/data/collector_index.py
@@ -4,489 +4,527 @@ EXAMPLE_INDEX = {
   'index_created': '2019-07-06 01:54',
   'build_revision': 'df98ac79',
   'path': 'https://collector.torproject.org',
-  'directories': {
-    'archive': {
-      'directories': {
-        'bridge-descriptors': {
-          'directories': {
-            'extra-infos': {
-              'files': {
-                'bridge-extra-infos-2008-05.tar.xz': {
+  'directories': [
+    {
+      'path': 'archive',
+      'directories': [
+        {
+          'path': 'bridge-descriptors',
+          'directories': [
+            {
+              'path': 'extra-infos',
+              'files': [
+                {
+                  'path': 'bridge-extra-infos-2008-05.tar.xz',
                   'size': 377644,
                   'last_modified': '2016-09-04 09:21'
-                },
-                'bridge-extra-infos-2008-06.tar.xz': {
+                }, {
+                  'path': 'bridge-extra-infos-2008-06.tar.xz',
                   'size': 600484,
                   'last_modified': '2016-09-04 09:21'
-                },
-                'bridge-extra-infos-2008-07.tar.xz': {
+                }, {
+                  'path': 'bridge-extra-infos-2008-07.tar.xz',
                   'size': 716320,
                   'last_modified': '2016-09-04 09:21'
                 }
-              }
-            },
-            'server-descriptors': {
-              'files': {
-                'bridge-server-descriptors-2008-05.tar.xz': {
+              ]
+            }, {
+              'path': 'server-descriptors',
+              'files': [
+                {
+                  'path': 'bridge-server-descriptors-2008-05.tar.xz',
                   'size': 205348,
                   'last_modified': '2016-09-09 14:13'
-                },
-                'bridge-server-descriptors-2008-06.tar.xz': {
+                }, {
+                  'path': 'bridge-server-descriptors-2008-06.tar.xz',
                   'size': 342828,
                   'last_modified': '2016-09-09 14:13'
-                },
-                'bridge-server-descriptors-2008-07.tar.xz': {
+                }, {
+                  'path': 'bridge-server-descriptors-2008-07.tar.xz',
                   'size': 374848,
                   'last_modified': '2016-09-09 14:13'
                 }
-              }
-            },
-            'statuses': {
-              'files': {
-                'bridge-statuses-2008-05.tar.xz': {
+              ]
+            }, {
+              'path': 'statuses',
+              'files': [
+                {
+                  'path': 'bridge-statuses-2008-05.tar.xz',
                   'size': 74792,
                   'last_modified': '2016-09-14 21:11'
-                },
-                'bridge-statuses-2008-06.tar.xz': {
+                }, {
+                  'path': 'bridge-statuses-2008-06.tar.xz',
                   'size': 123488,
                   'last_modified': '2016-09-14 21:11'
-                },
-                'bridge-statuses-2008-07.tar.xz': {
+                }, {
+                  'path': 'bridge-statuses-2008-07.tar.xz',
                   'size': 143836,
                   'last_modified': '2016-09-14 21:11'
                 }
-              }
+              ]
             }
-          }
-        },
-        'bridge-pool-assignments': {
-          'files': {
-            'bridge-pool-assignments-2010-09.tar.xz': {
+          ]
+        }, {
+          'path': 'bridge-pool-assignments',
+          'files': [
+            {
+              'path': 'bridge-pool-assignments-2010-09.tar.xz',
               'size': 32804,
               'last_modified': '2012-05-31 10:21'
-            },
-            'bridge-pool-assignments-2010-10.tar.xz': {
+            }, {
+              'path': 'bridge-pool-assignments-2010-10.tar.xz',
               'size': 304684,
               'last_modified': '2012-05-31 10:21'
-            },
-            'bridge-pool-assignments-2010-11.tar.xz': {
+            }, {
+              'path': 'bridge-pool-assignments-2010-11.tar.xz',
               'size': 292228,
               'last_modified': '2012-05-31 10:21'
             }
-          }
-        },
-        'exit-lists': {
-          'files': {
-            'exit-list-2010-02.tar.xz': {
+          ]
+        }, {
+          'path': 'exit-lists',
+          'files': [
+            {
+              'path': 'exit-list-2010-02.tar.xz',
               'size': 272008,
               'last_modified': '2012-05-31 18:57'
-            },
-            'exit-list-2010-03.tar.xz': {
+            }, {
+              'path': 'exit-list-2010-03.tar.xz',
               'size': 1247484,
               'last_modified': '2012-05-31 18:57'
-            },
-            'exit-list-2010-04.tar.xz': {
+            }, {
+              'path': 'exit-list-2010-04.tar.xz',
               'size': 1139896,
               'last_modified': '2012-05-31 18:57'
             }
-          }
-        },
-        'relay-descriptors': {
-          'files': {
-            'certs.tar.xz': {
+          ]
+        }, {
+          'path': 'relay-descriptors',
+          'files': [
+            {
+              'path': 'certs.tar.xz',
               'size': 144696,
               'last_modified': '2019-07-03 03:29'
             }
-          },
-          'directories': {
-            'bandwidths': {
-              'files': {
-                'bandwidths-2019-05.tar.xz': {
+          ],
+          'directories': [
+            {
+              'path': 'bandwidths',
+              'files': [
+                {
+                  'path': 'bandwidths-2019-05.tar.xz',
                   'size': 50385816,
                   'last_modified': '2019-06-07 08:05'
-                },
-                'bandwidths-2019-06.tar.xz': {
+                }, {
+                  'path': 'bandwidths-2019-06.tar.xz',
                   'size': 105881156,
                   'last_modified': '2019-07-03 07:30'
-                },
-                'bandwidths-2019-07.tar.xz': {
+                }, {
+                  'path': 'bandwidths-2019-07.tar.xz',
                   'size': 11374436,
                   'last_modified': '2019-07-03 07:12'
                 }
-              }
-            },
-            'consensuses': {
-              'files': {
-                'consensuses-2007-10.tar.xz': {
+              ]
+            }, {
+              'path': 'consensuses',
+              'files': [
+                {
+                  'path': 'consensuses-2007-10.tar.xz',
                   'size': 1061648,
                   'last_modified': '2012-05-15 14:35'
-                },
-                'consensuses-2007-11.tar.xz': {
+                }, {
+                  'path': 'consensuses-2007-11.tar.xz',
                   'size': 6810308,
                   'last_modified': '2012-05-15 14:35'
-                },
-                'consensuses-2007-12.tar.xz': {
+                }, {
+                  'path': 'consensuses-2007-12.tar.xz',
                   'size': 8106968,
                   'last_modified': '2012-05-15 14:35'
                 }
-              }
-            },
-            'extra-infos': {
-              'files': {
-                'extra-infos-2007-08.tar.xz': {
+              ]
+            }, {
+              'path': 'extra-infos',
+              'files': [
+                {
+                  'path': 'extra-infos-2007-08.tar.xz',
                   'size': 3016916,
                   'last_modified': '2016-06-23 09:53'
-                },
-                'extra-infos-2007-09.tar.xz': {
+                }, {
+                  'path': 'extra-infos-2007-09.tar.xz',
                   'size': 6459884,
                   'last_modified': '2016-06-23 09:54'
-                },
-                'extra-infos-2007-10.tar.xz': {
+                }, {
+                  'path': 'extra-infos-2007-10.tar.xz',
                   'size': 7326564,
                   'last_modified': '2016-06-23 09:54'
                 }
-              }
-            },
-            'microdescs': {
-              'files': {
-                'microdescs-2014-01.tar.xz': {
+              ]
+            }, {
+              'path': 'microdescs',
+              'files': [
+                {
+                  'path': 'microdescs-2014-01.tar.xz',
                   'size': 7515396,
                   'last_modified': '2014-02-07 03:59'
-                },
-                'microdescs-2014-02.tar.xz': {
+                }, {
+                  'path': 'microdescs-2014-02.tar.xz',
                   'size': 21822944,
                   'last_modified': '2014-03-07 04:54'
-                },
-                'microdescs-2014-03.tar.xz': {
+                }, {
+                  'path': 'microdescs-2014-03.tar.xz',
                   'size': 24201436,
                   'last_modified': '2014-04-07 03:54'
                 }
-              }
-            },
-            'server-descriptors': {
-              'files': {
-                'server-descriptors-2005-12.tar.xz': {
+              ]
+            }, {
+              'path': 'server-descriptors',
+              'files': [
+                {
+                  'path': 'server-descriptors-2005-12.tar.xz',
                   'size': 1348620,
                   'last_modified': '2016-06-24 08:12'
-                },
-                'server-descriptors-2006-02.tar.xz': {
+                }, {
+                  'path': 'server-descriptors-2006-02.tar.xz',
                   'size': 28625408,
                   'last_modified': '2016-06-24 08:14'
-                },
-                'server-descriptors-2006-03.tar.xz': {
+                }, {
+                  'path': 'server-descriptors-2006-03.tar.xz',
                   'size': 49548736,
                   'last_modified': '2016-06-24 08:17'
                 }
-              }
-            },
-            'statuses': {
-              'files': {
-                'statuses-2005-12.tar.xz': {
+              ]
+            }, {
+              'path': 'statuses',
+              'files': [
+                {
+                  'path': 'statuses-2005-12.tar.xz',
                   'size': 1468844,
                   'last_modified': '2016-06-25 11:50'
-                },
-                'statuses-2006-01.tar.xz': {
+                }, {
+                  'path': 'statuses-2006-01.tar.xz',
                   'size': 3344280,
                   'last_modified': '2016-06-25 11:52'
-                },
-                'statuses-2006-02.tar.xz': {
+                }, {
+                  'path': 'statuses-2006-02.tar.xz',
                   'size': 4006336,
                   'last_modified': '2016-06-25 11:54'
                 }
-              }
-            },
-            'tor': {
-              'files': {
-                'tor-2004-05.tar.xz': {
+              ]
+            }, {
+              'path': 'tor',
+              'files': [
+                {
+                  'path': 'tor-2004-05.tar.xz',
                   'size': 386672,
                   'last_modified': '2012-05-18 14:26'
-                },
-                'tor-2004-06.tar.xz': {
+                }, {
+                  'path': 'tor-2004-06.tar.xz',
                   'size': 1087980,
                   'last_modified': '2012-05-18 14:26'
-                },
-                'tor-2004-07.tar.xz': {
+                }, {
+                  'path': 'tor-2004-07.tar.xz',
                   'size': 1366568,
                   'last_modified': '2012-05-18 14:26'
                 }
-              }
-            },
-            'votes': {
-              'files': {
-                'votes-2007-10.tar.xz': {
+              ]
+            }, {
+              'path': 'votes',
+              'files': [
+                {
+                  'path': 'votes-2007-10.tar.xz',
                   'size': 1356504,
                   'last_modified': '2012-05-15 14:51'
-                },
-                'votes-2007-11.tar.xz': {
+                }, {
+                  'path': 'votes-2007-11.tar.xz',
                   'size': 10641492,
                   'last_modified': '2012-05-15 14:51'
-                },
-                'votes-2007-12.tar.xz': {
+                }, {
+                  'path': 'votes-2007-12.tar.xz',
                   'size': 14712136,
                   'last_modified': '2012-05-15 14:52'
                 }
-              }
+              ]
             }
-          }
-        },
-        'torperf': {
-          'files': {
-            'torperf-2009-07.tar.xz': {
+          ]
+        }, {
+          'path': 'torperf',
+          'files': [
+            {
+              'path': 'torperf-2009-07.tar.xz',
               'size': 182712,
               'last_modified': '2012-05-30 07:23'
-            },
-            'torperf-2009-08.tar.xz': {
+            }, {
+              'path': 'torperf-2009-08.tar.xz',
               'size': 203236,
               'last_modified': '2012-05-30 07:23'
-            },
-            'torperf-2009-09.tar.xz': {
+            }, {
+              'path': 'torperf-2009-09.tar.xz',
               'size': 193832,
               'last_modified': '2012-05-30 07:23'
             }
-          }
-        },
-        'webstats': {
-          'files': {
-            'webstats-2015-01.tar': {
+          ]
+        }, {
+          'path': 'webstats',
+          'files': [
+            {
+              'path': 'webstats-2015-01.tar',
               'size': 30720,
               'last_modified': '2018-03-19 16:07'
-            },
-            'webstats-2015-02.tar': {
+            }, {
+              'path': 'webstats-2015-02.tar',
               'size': 20480,
               'last_modified': '2018-03-19 16:07'
-            },
-            'webstats-2015-03.tar': {
+            }, {
+              'path': 'webstats-2015-03.tar',
               'size': 20480,
               'last_modified': '2018-03-19 16:07'
             }
-          }
+          ]
         }
-      }
-    },
-    'contrib': {},
-    'recent': {
-      'directories': {
-        'bridge-descriptors': {
-          'directories': {
-            'extra-infos': {
-              'files': {
-                '2019-07-03-02-09-00-extra-infos': {
+      ]
+    }, {
+      'path': 'contrib'
+    }, {
+      'path': 'recent',
+      'directories': [
+        {
+          'path': 'bridge-descriptors',
+          'directories': [
+            {
+              'path': 'extra-infos',
+              'files': [
+                {
+                  'path': '2019-07-03-02-09-00-extra-infos',
                   'size': 507816,
                   'last_modified': '2019-07-03 02:09'
-                },
-                '2019-07-03-03-09-00-extra-infos': {
+                }, {
+                  'path': '2019-07-03-03-09-00-extra-infos',
                   'size': 558790,
                   'last_modified': '2019-07-03 03:09'
-                },
-                '2019-07-03-04-09-05-extra-infos': {
+                }, {
+                  'path': '2019-07-03-04-09-05-extra-infos',
                   'size': 592279,
                   'last_modified': '2019-07-03 04:09'
                 }
-              }
-            },
-            'server-descriptors': {
-              'files': {
-                '2019-07-03-02-09-00-server-descriptors': {
+              ]
+            }, {
+              'path': 'server-descriptors',
+              'files': [
+                {
+                  'path': '2019-07-03-02-09-00-server-descriptors',
                   'size': 274355,
                   'last_modified': '2019-07-03 02:09'
-                },
-                '2019-07-03-03-09-00-server-descriptors': {
+                }, {
+                  'path': '2019-07-03-03-09-00-server-descriptors',
                   'size': 295671,
                   'last_modified': '2019-07-03 03:09'
-                },
-                '2019-07-03-04-09-05-server-descriptors': {
+                }, {
+                  'path': '2019-07-03-04-09-05-server-descriptors',
                   'size': 312822,
                   'last_modified': '2019-07-03 04:09'
                 }
-              }
-            },
-            'statuses': {
-              'files': {
-                '20190703-011231-BA44A889E64B93FAA2B114E02C2A279A8555C533': {
+              ]
+            }, {
+              'path': 'statuses',
+              'files': [
+                {
+                  'path': '20190703-011231-BA44A889E64B93FAA2B114E02C2A279A8555C533',
                   'size': 238340,
                   'last_modified': '2019-07-03 02:09'
-                },
-                '20190703-014231-BA44A889E64B93FAA2B114E02C2A279A8555C533': {
+                }, {
+                  'path': '20190703-014231-BA44A889E64B93FAA2B114E02C2A279A8555C533',
                   'size': 238147,
                   'last_modified': '2019-07-03 02:09'
-                },
-                '20190703-021231-BA44A889E64B93FAA2B114E02C2A279A8555C533': {
+                }, {
+                  'path': '20190703-021231-BA44A889E64B93FAA2B114E02C2A279A8555C533',
                   'size': 238231,
                   'last_modified': '2019-07-03 03:09'
                 }
-              }
+              ]
             }
-          }
-        },
-        'exit-lists': {
-          'files': {
-            '2019-07-03-02-02-00': {
+          ]
+        }, {
+          'path': 'exit-lists',
+          'files': [
+            {
+              'path': '2019-07-03-02-02-00',
               'size': 158516,
               'last_modified': '2019-07-03 02:02'
-            },
-            '2019-07-03-03-02-00': {
+            }, {
+              'path': '2019-07-03-03-02-00',
               'size': 158830,
               'last_modified': '2019-07-03 03:02'
-            },
-            '2019-07-03-04-02-00': {
+            }, {
+              'path': '2019-07-03-04-02-00',
               'size': 158831,
               'last_modified': '2019-07-03 04:02'
             }
-          }
-        },
-        'relay-descriptors': {
-          'directories': {
-            'bandwidths': {
-              'files': {
-                '2019-07-03-00-30-57-bandwidth-616DF2278EE2C90F475E4EA2562E2C00EB9F10E517FB901229F331AEB70B8AD7': {
+          ]
+        }, {
+          'path': 'relay-descriptors',
+          'directories': [
+            {
+              'path': 'bandwidths',
+              'files': [
+                {
+                  'path': '2019-07-03-00-30-57-bandwidth-616DF2278EE2C90F475E4EA2562E2C00EB9F10E517FB901229F331AEB70B8AD7',
                   'size': 2580044,
                   'last_modified': '2019-07-03 02:35'
-                },
-                '2019-07-03-01-35-02-bandwidth-2A5B679E9AA2D5C903CD16C00E16FEFA3E21E38AB3DE338941AE4AC13FD505DE': {
+                }, {
+                  'path': '2019-07-03-01-35-02-bandwidth-2A5B679E9AA2D5C903CD16C00E16FEFA3E21E38AB3DE338941AE4AC13FD505DE',
                   'size': 4210146,
                   'last_modified': '2019-07-03 02:35'
-                },
-                '2019-07-03-01-35-03-bandwidth-3B06DAD9EDE8E1D08CC494E856AFD9D49256ECC2D68456799DD1EC7ED3436875': {
+                }, {
+                  'path': '2019-07-03-01-35-03-bandwidth-3B06DAD9EDE8E1D08CC494E856AFD9D49256ECC2D68456799DD1EC7ED3436875',
                   'size': 4249699,
                   'last_modified': '2019-07-03 02:35'
                 }
-              }
-            },
-            'consensuses': {
-              'files': {
-                '2019-07-03-02-00-00-consensus': {
+              ]
+            }, {
+              'path': 'consensuses',
+              'files': [
+                {
+                  'path': '2019-07-03-02-00-00-consensus',
                   'size': 2211265,
                   'last_modified': '2019-07-03 02:05'
-                },
-                '2019-07-03-03-00-00-consensus': {
+                }, {
+                  'path': '2019-07-03-03-00-00-consensus',
                   'size': 2204478,
                   'last_modified': '2019-07-03 03:05'
-                },
-                '2019-07-03-04-00-00-consensus': {
+                }, {
+                  'path': '2019-07-03-04-00-00-consensus',
                   'size': 2202554,
                   'last_modified': '2019-07-03 04:05'
                 }
-              }
-            },
-            'extra-infos': {
-              'files': {
-                '2019-07-03-02-05-00-extra-infos': {
+              ]
+            }, {
+              'path': 'extra-infos',
+              'files': [
+                {
+                  'path': '2019-07-03-02-05-00-extra-infos',
                   'size': 1162899,
                   'last_modified': '2019-07-03 02:05'
-                },
-                '2019-07-03-03-05-00-extra-infos': {
+                }, {
+                  'path': '2019-07-03-03-05-00-extra-infos',
                   'size': 1133425,
                   'last_modified': '2019-07-03 03:05'
-                },
-                '2019-07-03-04-05-00-extra-infos': {
+                }, {
+                  'path': '2019-07-03-04-05-00-extra-infos',
                   'size': 1153793,
                   'last_modified': '2019-07-03 04:05'
                 }
-              }
-            },
-            'microdescs': {
-              'directories': {
-                'consensus-microdesc': {
-                  'files': {
-                    '2019-07-03-02-00-00-consensus-microdesc': {
+              ]
+            }, {
+              'path': 'microdescs',
+              'directories': [
+                {
+                  'path': 'consensus-microdesc',
+                  'files': [
+                    {
+                      'path': '2019-07-03-02-00-00-consensus-microdesc',
                       'size': 2028994,
                       'last_modified': '2019-07-03 02:05'
-                    },
-                    '2019-07-03-03-00-00-consensus-microdesc': {
+                    }, {
+                      'path': '2019-07-03-03-00-00-consensus-microdesc',
                       'size': 2022808,
                       'last_modified': '2019-07-03 03:05'
-                    },
-                    '2019-07-03-04-00-00-consensus-microdesc': {
+                    }, {
+                      'path': '2019-07-03-04-00-00-consensus-microdesc',
                       'size': 2020751,
                       'last_modified': '2019-07-03 04:05'
                     }
-                  }
-                },
-                'micro': {
-                  'files': {
-                    '2019-07-02-23-05-00-micro': {
+                  ]
+                }, {
+                  'path': 'micro',
+                  'files': [
+                    {
+                      'path': '2019-07-02-23-05-00-micro',
                       'size': 19934,
                       'last_modified': '2019-07-02 23:05'
-                    },
-                    '2019-07-03-00-05-00-micro': {
+                    }, {
+                      'path': '2019-07-03-00-05-00-micro',
                       'size': 12030,
                       'last_modified': '2019-07-03 00:05'
-                    },
-                    '2019-07-03-01-05-00-micro': {
+                    }, {
+                      'path': '2019-07-03-01-05-00-micro',
                       'size': 14850,
                       'last_modified': '2019-07-03 01:05'
                     }
-                  }
+                  ]
                 }
-              }
-            },
-            'server-descriptors': {
-              'files': {
-                '2019-07-03-02-05-00-server-descriptors': {
+              ]
+            }, {
+              'path': 'server-descriptors',
+              'files': [
+                {
+                  'path': '2019-07-03-02-05-00-server-descriptors',
                   'size': 1374587,
                   'last_modified': '2019-07-03 02:05'
-                },
-                '2019-07-03-03-05-00-server-descriptors': {
+                }, {
+                  'path': '2019-07-03-03-05-00-server-descriptors',
                   'size': 1353286,
                   'last_modified': '2019-07-03 03:05'
-                },
-                '2019-07-03-04-05-00-server-descriptors': {
+                }, {
+                  'path': '2019-07-03-04-05-00-server-descriptors',
                   'size': 1336125,
                   'last_modified': '2019-07-03 04:05'
                 }
-              }
-            },
-            'votes': {
-              'files': {
-                '2019-07-03-02-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-D9B6923A3AF9FB5DB3CD30191BCBD29A7A936D86': {
+              ]
+            }, {
+              'path': 'votes',
+              'files': [
+                {
+                  'path': '2019-07-03-02-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-D9B6923A3AF9FB5DB3CD30191BCBD29A7A936D86',
                   'size': 3449707,
                   'last_modified': '2019-07-03 02:05'
-                },
-                '2019-07-03-02-00-00-vote-14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4-39429F0789A9EC07A2A8754C4C449CCABAB787CC': {
+                }, {
+                  'path': '2019-07-03-02-00-00-vote-14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4-39429F0789A9EC07A2A8754C4C449CCABAB787CC',
                   'size': 3435482,
                   'last_modified': '2019-07-03 02:05'
-                },
-                '2019-07-03-02-00-00-vote-23D15D965BC35114467363C165C4F724B64B4F66-4337842B697467123B5351E1E8EB64ED497C0EDA': {
+                }, {
+                  'path': '2019-07-03-02-00-00-vote-23D15D965BC35114467363C165C4F724B64B4F66-4337842B697467123B5351E1E8EB64ED497C0EDA',
                   'size': 3571106,
                   'last_modified': '2019-07-03 02:05'
                 }
-              }
+              ]
             }
-          }
-        },
-        'torperf': {
-          'files': {
-            'op-ab-1048576-2019-07-03.tpf': {
+          ]
+        }, {
+          'path': 'torperf',
+          'files': [
+            {
+              'path': 'op-ab-1048576-2019-07-03.tpf',
               'size': 39152,
               'last_modified': '2019-07-04 00:01'
-            },
-            'op-ab-51200-2019-07-03.tpf': {
+            }, {
+              'path': 'op-ab-51200-2019-07-03.tpf',
               'size': 248173,
               'last_modified': '2019-07-04 00:01'
-            },
-            'op-ab-5242880-2019-07-03.tpf': {
+            }, {
+              'path': 'op-ab-5242880-2019-07-03.tpf',
               'size': 15900,
               'last_modified': '2019-07-04 00:01'
             }
-          }
-        },
-        'webstats': {
-          'files': {
-            '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190620.xz': {
+          ]
+        }, {
+          'path': 'webstats',
+          'files': [
+            {
+              'path': '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190620.xz',
               'size': 8872,
               'last_modified': '2019-07-03 04:21'
-            },
-            '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190621.xz': {
+            }, {
+              'path': '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190621.xz',
               'size': 9312,
               'last_modified': '2019-07-04 04:21'
-            },
-            '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190622.xz': {
+            }, {
+              'path': '2019.www.torproject.org_hetzner-hel1-03.torproject.org_access.log_20190622.xz',
               'size': 9836,
               'last_modified': '2019-07-05 04:21'
             }
-          }
+          ]
         }
-      }
+      ]
     }
-  }
+  ]
 }





More information about the tor-commits mailing list