Display more info while grouping
[compass/delber.git] / app.py
bloba0d2b057469de139ce1a5791e6b2c426c0486817
1 import os
2 import re
3 import compass
4 from flask import Flask, request, redirect, render_template, url_for
6 app = Flask(__name__)
8 class Opt(object):
9 def __init__(self):
10 self.by_as = False
11 self.family = None
12 self.by_country = False
13 self.ases = None
14 self.country = None
15 self.top = -1
16 self.short = None
17 self.links = None
18 self.guards_only = None
19 self.inactive = False
20 self.almost_fast_exits_only = None
21 self.exits_only = False
22 self.download = None
23 self.fast_exits_only = False
24 self.fast_exits_only_any_network = False
25 self.all_relays = False
27 class Result():
28 def __init__(self):
29 self.cw = None
30 self.adv_bw = None
31 self.p_guard = None
32 self.p_exit = None
33 self.p_middle = None
34 self.nick = None
35 self.fp = None
36 self.link = None
37 self.exit = None
38 self.guard = None
39 self.cc = None
40 self.as_no = None
41 self.as_name = None
42 self.as_info = None
44 def parse(output_string, grouping=False, sort_key=None):
45 results = []
46 sorted_results = {}
48 for id, line in enumerate(output_string):
49 # skip headings
50 if id == 0: continue
52 result = Result()
53 values = line.split()
55 """
56 This is a super weird hack. When we group by country or AS, the
57 nickname is replaced with '(x relays)' which when split() creates
58 ['(x','relays)']. I need to join this again and then left shift all
59 the elements and delete the last element in the list.
60 """
61 if grouping:
62 values[6] = "%s %s" % (values[6], values[7])
63 for id in xrange(8, len(values)):
64 values[id-1] = values[id]
65 del values[-1]
67 # TODO: change inaccurate value of 10
68 if len(values) > 10:
69 result.cw = values[0]
70 result.adv_bw = values[1]
71 result.p_guard = values[2]
72 result.p_middle = values[3]
73 result.p_exit = values[4]
74 result.nick = values[5]
75 result.fp = values[6]
76 result.exit = values[7]
77 result.guard = values[8]
78 result.cc = values[9]
79 result.as_no = values[10]
80 result.as_name = ' '.join(values[11:])
81 result.as_name = re.sub(r'\([^)]*\)', '', result.as_name)
82 result.as_info = "%s %s" % (result.as_no, result.as_name)
84 if sort_key:
85 key = float(getattr(result, sort_key)[:-1])
86 if sorted_results.has_key(key):
87 sorted_results[key].append(result)
88 else:
89 sorted_results[key] = [result]
90 else:
91 results.append(result)
92 return results if results else sorted_results
94 @app.route('/')
95 def index():
96 return render_template('index.html')
98 @app.route('/result', methods=['GET'])
99 def result():
100 options = Opt()
101 sort_key = None
102 relays = []
104 for key, value in request.args.items():
105 if key == "top":
106 try:
107 options.top = int(value)
108 except:
109 options.top = -1
110 elif key == "sort":
111 sort_key = value
112 elif key in ["country", "ases"]:
113 if value:
114 setattr(options, key, [value])
115 else:
116 setattr(options, key, None)
117 elif key == "exits":
118 setattr(options, value, True)
119 else:
120 setattr(options, key, value)
122 stats = compass.RelayStats(options)
123 sorted_groups = stats.format_and_sort_groups(stats.relays,
124 by_country=options.by_country,
125 by_as_number=options.by_as,
126 links=options.links)
127 output_string = stats.print_groups(sorted_groups, options.top,
128 by_country=options.by_country,
129 by_as_number=options.by_as,
130 short=None,
131 links=None)
132 results = parse(output_string, options.by_country or options.by_as, sort_key)
134 if sort_key:
135 for key in sorted(results.iterkeys(), reverse=True):
136 for value in results[key]:
137 relays.append(value)
138 else:
139 relays = results
141 return render_template('result.html', results=relays)
143 if __name__ == '__main__':
144 # Bind to PORT if defined, otherwise default to 5000.
145 port = int(os.environ.get('PORT', 5000))
146 app.run(host='0.0.0.0', port=port, debug=True)