[tor-commits] [compass/master] Rebuilt the Option class to be a little more usable from the web front-end
karsten at torproject.org
karsten at torproject.org
Mon Jan 7 07:09:40 UTC 2013
commit e1b2e15dc56f6c3d0d6d032a893159e88e9a2d4f
Author: Chris Wacek <cwacek at cs.georgetown.edu>
Date: Wed Dec 12 23:12:06 2012 -0500
Rebuilt the Option class to be a little more usable from the web front-end
---
app.py | 71 +++++++++++++++++++++++++++++------------------------------
compass.py | 58 ++++++++++++++++++++++++++++++++++++++-----------
util.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 139 insertions(+), 49 deletions(-)
diff --git a/app.py b/app.py
index 3a66a79..67f4608 100644
--- a/app.py
+++ b/app.py
@@ -1,46 +1,45 @@
import os
import re
import compass
-from flask import Flask, request, redirect, render_template, url_for
+from util import Result,Boolean,NullFn,Int,Container
+from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
class Opt(object):
- def __init__(self):
- self.by_as = False
- self.family = None
- self.by_country = False
- self.ases = None
- self.country = None
- self.top = -1
- self.short = None
- self.links = None
- self.guards_only = None
- self.inactive = False
- self.almost_fast_exits_only = None
- self.exits_only = False
- self.download = None
- self.fast_exits_only = False
- self.fast_exits_only_any_network = False
- self.all_relays = False
+ request_types = {
+ 'by_as':Boolean,
+ 'by_country':Boolean,
+ 'inactive':Boolean,
+ 'exits_only':Boolean,
+ 'guards_only': Boolean,
+ 'links':Boolean,
+ 'sort':NullFn,
+ 'sort_reverse':Boolean,
+ 'top':Int,
+ 'family':NullFn,
+ 'ases':NullFn,
+ 'country':Container,
+ 'exit_filter':NullFn
+ }
-class Result():
- def __init__(self):
- self.index = None
- self.cw = None
- self.adv_bw = None
- self.p_guard = None
- self.p_exit = None
- self.p_middle = None
- self.nick = None
- self.fp = None
- self.link = None
- self.exit = None
- self.guard = None
- self.cc = None
- self.as_no = None
- self.as_name = None
- self.as_info = None
+ @staticmethod
+ def convert(key,val):
+ return Opt.request_types[key](val)
+
+ def __str__(self):
+ return repr(self)
+
+ def __repr__(self):
+ return str(self.__dict__)
+
+ def __init__(self,request):
+
+ for key in Opt.request_types:
+ if key in request:
+ setattr(self,key,Opt.convert(key,request[key]))
+ else:
+ setattr(self,key,Opt.convert(key,None))
def parse(output_string, grouping=False, sort_key=None):
results = []
diff --git a/compass.py b/compass.py
index a62eb98..520a017 100755
--- a/compass.py
+++ b/compass.py
@@ -18,6 +18,7 @@ ALMOST_FAST_EXIT_PORTS = [80, 443]
import json
import operator
import sys
+import util
import os
from optparse import OptionParser, OptionGroup
import urllib
@@ -221,15 +222,16 @@ class RelayStats(object):
filters.append(ExitFilter())
if options.guards_only:
filters.append(GuardFilter())
- if options.fast_exits_only:
+ if options.exit_filter == 'all_relays':
+ pass
+ elif options.exit_filter == 'fast_exits_only':
filters.append(SameNetworkFilter(FastExitFilter()))
- if options.almost_fast_exits_only:
- filters.append(
- FastExitFilter(ALMOST_FAST_EXIT_BANDWIDTH_RATE, ALMOST_FAST_EXIT_ADVERTISED_BANDWIDTH,
- ALMOST_FAST_EXIT_PORTS))
- filters.append(
- InverseFilter(SameNetworkFilter(FastExitFilter())))
- if options.fast_exits_only_any_network:
+ elif options.exit_filter == 'almost_fast_exits_only':
+ filters.append(FastExitFilter(ALMOST_FAST_EXIT_BANDWIDTH_RATE,
+ ALMOST_FAST_EXIT_ADVERTISED_BANDWIDTH,
+ ALMOST_FAST_EXIT_PORTS))
+ filters.append(InverseFilter(SameNetworkFilter(FastExitFilter())))
+ elif options.exit_filter == 'fast_exits_only_any_network':
filters.append(FastExitFilter())
return filters
@@ -364,6 +366,9 @@ def create_option_parser():
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("--exit-filter",type="choice", dest="exit_filter",
+ choices=["fast_exits_only","almost_fast_exits_only",
+ "all_relays","fast_exits_only_any_network"])
group.add_option("--fast-exits-only", action="store_true",
help="select only fast exits (%d+ Mbit/s, %d+ KB/s, %s, %d- per /24)" %
(FAST_EXIT_BANDWIDTH_RATE / (125 * 1024),
@@ -404,6 +409,32 @@ def download_details_file():
url.close()
details_file.close()
+def fix_exit_filter_options(options):
+ """
+ Translate the old-style exit filter options into
+ the new format (as received on the front end).
+ """
+ if options.exit_filter != "all_relays":
+ # We just accept this option's value
+ return options
+
+ fast_exit_options = 0
+ if options.fast_exits_only:
+ options.exit_filter = "fast_exits_only"
+ fast_exit_options += 1
+ if options.almost_fast_exits_only:
+ options.exit_filter = "almost_fast_exits_only"
+ fast_exit_options += 1
+ if options.fast_exits_only_any_network:
+ options.exit_filter = "fast_exits_only_any_network"
+ fast_exit_options += 1
+
+ if fast_exit_options > 1:
+ raise Exception
+
+ return options
+
+
if '__main__' == __name__:
parser = create_option_parser()
(options, args) = parser.parse_args()
@@ -411,12 +442,12 @@ if '__main__' == __name__:
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)
- fast_exit_options = 0
- if options.fast_exits_only: fast_exit_options += 1
- if options.almost_fast_exits_only: fast_exit_options += 1
- if options.fast_exits_only_any_network: fast_exit_options += 1
- if fast_exit_options > 1:
+
+ try:
+ fix_exit_filter_options(options)
+ except:
parser.error("Can only filter by one fast-exit option.")
+
if options.download:
download_details_file()
print "Downloaded details.json. Re-run without --download option."
@@ -430,6 +461,7 @@ if '__main__' == __name__:
by_country=options.by_country,
by_as_number=options.by_as,
links=options.links)
+
output_string = stats.print_groups(sorted_groups, options.top,
by_country=options.by_country,
by_as_number=options.by_as,
diff --git a/util.py b/util.py
new file mode 100644
index 0000000..d5d041e
--- /dev/null
+++ b/util.py
@@ -0,0 +1,59 @@
+import json
+
+def Container(val):
+ return json.loads(val)
+
+def NullFn(val):
+ return val
+
+def Int(val):
+ try:
+ return int(val)
+ except:
+ return None
+
+def Boolean(val):
+ if val == True:
+ return True
+
+ if val in ("false", "False", "FALSE", "F"):
+ return False
+ if val in ("true", "True", "TRUE", "T"):
+ return True
+
+ return False
+
+class Result():
+ WEIGHT_FIELDS = {
+ 'consensus_weight_fraction': 'cw',
+ 'advertised_bandwidth_fraction': 'adv_bw',
+ 'guard_probability': 'p_guard',
+ 'middle_probability': 'p_middle',
+ 'exit_probability': 'p_exit',
+ }
+
+ def __init__(self):
+ self.index = None
+ self.cw = None
+ self.adv_bw = None
+ self.p_guard = None
+ self.p_exit = None
+ self.p_middle = None
+ self.nick = None
+ self.fp = None
+ self.link = None
+ self.exit = None
+ self.guard = None
+ self.cc = None
+ self.as_no = None
+ self.as_name = None
+ self.as_info = None
+
+ def __getitem__(self,prop):
+ getattr(self,prop)
+
+ def __setitem__(self,prop,val):
+ setattr(self,prop,val)
+
+ def jsonify(self):
+ return self.__dict__
More information about the tor-commits
mailing list