Hi Karsten. After thinking about this for a bit I'm gonna vote for #4. :)
DocTor's consensus-health page is solely used by authority operators, and only for specific tasks. If its current visualization of this information was truly helpful then I'd agree that we should keep it. However, for the use case Roger mentioned...
"i wanted to know how many relays had a Running flag from those two authorities and no Running flag from any others"
... means he had to either...
a. Read through ~4,000 entries on that page, counting how many fit his critera. b. curl the page and grep the html for what he wanted
Either one sounds terrible, and I sincerely hope we have better uses for Roger's time. If we can persuade him to give us the use cases for what he wants from consensus-health then I think we can come up with better alternatives. Possibly a suite of scripts that give him the answers to common questions (and can be adapted for more exotic ones). For instance, in this case something like the following would've done the trick...
======================================== Compares the Running flag between moria1 and maatuska ========================================
from stem.descriptor import DocumentHandler, remote
# Query each authority with a v3ident for its vote.
downloader = remote.DescriptorDownloader(document_handler = DocumentHandler.DOCUMENT) queries = {}
for authority in remote.get_authorities().values(): if authority.v3ident is not None: queries[authority.nickname] = downloader.get_vote(authority)
# Wait for the votes to finish being downloaded, this produces a dictionary of # authority nicknames to their vote.
votes = dict((nickname, query.run()[0]) for (nickname, query) in queries.items())
# Get the superset of all relay fingerprints in the votes.
all_fingerprints = set()
for vote in votes.values(): all_fingerprints.update(vote.routers.keys())
# For each relay check if it has the 'Running' flag from moria1 but not # maatuska.
for fingerprint in all_fingerprints: moria1_vote = votes['moria1'].routers.get(fingerprint) maatuska_vote = votes['maatuska'].routers.get(fingerprint)
if not moria1_vote and not maatuska_vote: print "both moria1 and maatuska haven't voted about %s" % fingerprint if not moria1_vote: print "moria1 hasn't voted about %s" % fingerprint elif not maatuska_vote: print "maatuska hasn't voted about %s" % fingerprint elif 'Running' in moria1_vote.flags and 'Running' not in maatuska_vote.flags: print "moria1 has the Running flag but maatuska doesn't: %s" % fingerprint elif 'Running' in maatuska_vote.flags and 'Running' not in moria1_vote.flags: print "maatuska has the Running flag but moria1 doesn't: %s" % fingerprint
========================================
atagar@odin:~/Desktop/stem$ python example.py maatuska has the Running flag but moria1 doesn't: 32A38850B20858B0AC2DF5D5FAFB7F3596161067 maatuska has the Running flag but moria1 doesn't: D3FE846B0DD32285B1D5B3FCF8649040BC6D4CC3 maatuska has the Running flag but moria1 doesn't: 6871F682350BA931838C0EC1E4A23044DAE06A73 moria1 has the Running flag but maatuska doesn't: 8047A4D403EAC6BA15D68D4D93626CDF84B0BC4B moria1 hasn't voted about 1D3E139EB1917EBA0B594607D61CD99F733A8CB9 both moria1 and maatuska haven't voted about 834D996C76C73A78E23B8F41CA2AC476776D4CA8 ... etc...
========================================
Cheers! -Damian