[tor-commits] [metrics-tasks/master] Select family by fingerprint or nickname (for named relays) (#6329)

karsten at torproject.org karsten at torproject.org
Fri Aug 3 11:59:48 UTC 2012


commit 1a40e101d09223e09132f3eea5c20074318b69ce
Author: Michael Zeltner <m at niij.org>
Date:   Sat Jul 28 21:19:02 2012 +0200

    Select family by fingerprint or nickname (for named relays) (#6329)
---
 task-6329/tor-relays-stats.py |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/task-6329/tor-relays-stats.py b/task-6329/tor-relays-stats.py
index 1e4159e..b6dd24c 100755
--- a/task-6329/tor-relays-stats.py
+++ b/task-6329/tor-relays-stats.py
@@ -12,6 +12,7 @@ import sys
 import os.path
 from optparse import OptionParser, OptionGroup
 import urllib
+import re
 
 class RelayStats(object):
     def __init__(self):
@@ -23,13 +24,40 @@ class RelayStats(object):
             self._data = json.load(file('details.json'))
         return self._data
 
-    def get_relays(self, countries=[], as_sets=[], exits_only=False, guards_only=False, inactive=False, fast_exits_only=False):
+    def get_relays(self, countries=[], as_sets=[], exits_only=False, guards_only=False, inactive=False, fast_exits_only=False, family=None):
         relays = []
+        family_fingerprint = None
+        family_nickname = None
+        family_relays = []
         if countries:
             countries = [x.lower() for x in countries]
         if as_sets:
             as_sets = [x if not x.isdigit() else "AS" + x for x in as_sets]
+        if family:
+            fingerprint = family if len(family) == 40 else None
+            nickname = family if len(family) < 20 else None
+            found_relay = None
+            for relay in self.data['relays']:
+                if fingerprint and relay['fingerprint'] == fingerprint:
+                    found_relay = relay
+                    break
+                if nickname and 'Named' in relay['flags'] and relay['nickname'] == nickname:
+                    found_relay = relay
+                    break
+            if found_relay:
+                family_fingerprint = '$%s' % found_relay.get('fingerprint')
+                family_nickname = found_relay['nickname'] if 'Named' in found_relay['flags'] else None
+                family_relays = found_relay.get('family', [])
+                family_relays.append(family_fingerprint)
         for relay in self.data['relays']:
+            if family:
+               mentions = relay.get('family', [])
+               mentions.append('%s' % relay['fingerprint'])
+               if ('$%s' % relay['fingerprint'] not in family_relays and \
+                  relay['nickname'] not in family_relays if 'Named' in relay['flags'] else '') or \
+                  (family_fingerprint not in mentions and \
+                  family_nickname not in mentions):
+                   continue
             if not inactive and inactive == relay['running']:
                 continue
             if countries and not relay.get('country', ' ') in countries:
@@ -185,6 +213,8 @@ if '__main__' == __name__:
                      help="select only relays from country with code CC", metavar="CC")
     group.add_option("-e", "--exits-only", action="store_true",
                      help="select only relays suitable for exit position")
+    group.add_option("-f", "--family", action="store", type="string", metavar="RELAY",
+                     help="select family by fingerprint or nickname (for named relays)")
     group.add_option("-g", "--guards-only", action="store_true",
                      help="select only relays suitable for guard position")
     group.add_option("-x", "--fast-exits-only", action="store_true",
@@ -208,6 +238,8 @@ if '__main__' == __name__:
     if len(args) > 0:
         parser.error("Did not understand positional argument(s), use options instead.")
 
+    if options.family and not re.match(r'^[A-F0-9]{40}$', options.family) and not re.match(r'^[A-Za-z0-9]{1,19}$', options.family):
+        parser.error("Not a valid fingerprint or nickname: %s" % options.family)
     if options.download:
         download_details_file()
         print "Downloaded details.json.  Re-run without --download option."
@@ -222,7 +254,8 @@ if '__main__' == __name__:
                               exits_only=options.exits_only,
                               guards_only=options.guards_only,
                               inactive=options.inactive,
-                              fast_exits_only=options.fast_exits_only)
+                              fast_exits_only=options.fast_exits_only,
+                              family=options.family)
     grouped_relays = stats.group_relays(relays,
                      by_country=options.by_country,
                      by_as_number=options.by_as)



More information about the tor-commits mailing list