diff options
Diffstat (limited to 'generate_tox_bootstrap.py')
-rw-r--r-- | generate_tox_bootstrap.py | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/generate_tox_bootstrap.py b/generate_tox_bootstrap.py new file mode 100644 index 0000000..44281c9 --- /dev/null +++ b/generate_tox_bootstrap.py | |||
@@ -0,0 +1,146 @@ | |||
1 | #!/usr/bin/python | ||
2 | # pip install jinja2 requests | ||
3 | |||
4 | import datetime | ||
5 | import jinja2 | ||
6 | import json | ||
7 | import requests | ||
8 | import socket | ||
9 | |||
10 | json_url = 'https://nodes.tox.chat/json' | ||
11 | |||
12 | tox_bootstrap_template = """ | ||
13 | /* | ||
14 | * Generated with generate_tox_bootstrap.py by GDR! | ||
15 | * from {{ json_url }} on {{ now }} | ||
16 | */ | ||
17 | struct bootstrap_node { | ||
18 | char *address; | ||
19 | uint16_t port; | ||
20 | uint8_t key[32]; | ||
21 | } bootstrap_nodes[] = { | ||
22 | {% for node in nodes %} | ||
23 | { | ||
24 | "{{ node.ipv4 }}", | ||
25 | {{ node.port }}, | ||
26 | { | ||
27 | {{ node.public_key|toxtoc }} | ||
28 | } | ||
29 | }, | ||
30 | {% endfor %} | ||
31 | { | ||
32 | "176.31.28.63", | ||
33 | 6881, | ||
34 | { | ||
35 | 0x0B, 0x6C, 0x7A, 0x93, 0xA6, 0xD8, 0xC0, 0xEB, 0x44, 0x96, 0x5C, 0x4A, 0x85, 0xCB, 0x88, 0xBA, | ||
36 | 0x75, 0x71, 0x17, 0x0F, 0xE2, 0xDB, 0x3D, 0xEA, 0x10, 0x71, 0x3E, 0x48, 0x55, 0x9A, 0x55, 0x4D | ||
37 | } | ||
38 | }, | ||
39 | }; | ||
40 | |||
41 | struct bootstrap_node tcp_relays[] = { | ||
42 | {% for node in relays %} | ||
43 | { | ||
44 | "{{ node.ipv4 }}", | ||
45 | {{ node.port }}, | ||
46 | { | ||
47 | {{ node.public_key|toxtoc }} | ||
48 | } | ||
49 | }, | ||
50 | {% endfor %} | ||
51 | { | ||
52 | "176.31.28.63", | ||
53 | 465, | ||
54 | { | ||
55 | 0x0B, 0x6C, 0x7A, 0x93, 0xA6, 0xD8, 0xC0, 0xEB, 0x44, 0x96, 0x5C, 0x4A, 0x85, 0xCB, 0x88, 0xBA, | ||
56 | 0x75, 0x71, 0x17, 0x0F, 0xE2, 0xDB, 0x3D, 0xEA, 0x10, 0x71, 0x3E, 0x48, 0x55, 0x9A, 0x55, 0x4D | ||
57 | } | ||
58 | }, | ||
59 | }; | ||
60 | """ | ||
61 | |||
62 | def toxtoc(value): | ||
63 | """ | ||
64 | A Jinja2 filter to turn a ToxID into two lines of C bytes | ||
65 | """ | ||
66 | def get_16_bytes(value): | ||
67 | """ | ||
68 | Generate 1 line of C code - 16 bytes | ||
69 | @param value a hex string of length 32 (32 hex chars) | ||
70 | """ | ||
71 | if len(value) <> 32: | ||
72 | raise ValueError('%r is not a 32-char string') | ||
73 | |||
74 | rv = "" | ||
75 | |||
76 | for i in range(16): | ||
77 | rv += "0x%s" % value[2*i : 2*i+2] | ||
78 | if i < 15: | ||
79 | rv += ", " | ||
80 | |||
81 | return rv | ||
82 | |||
83 | rv = get_16_bytes(value[:32]) + \ | ||
84 | ",\n" + (12*' ') + \ | ||
85 | get_16_bytes(value[32:]) | ||
86 | |||
87 | return rv | ||
88 | |||
89 | class Loader(jinja2.BaseLoader): | ||
90 | def get_source(self, environment, template): | ||
91 | return tox_bootstrap_template, 'tox_bootstrap_template', True | ||
92 | |||
93 | if __name__ == "__main__": | ||
94 | r = requests.get(json_url) | ||
95 | data = r.json() | ||
96 | if 'nodes' not in data: | ||
97 | raise ValueError('nodes element not in JSON') | ||
98 | |||
99 | nodes = [] | ||
100 | tcp_relays = [] | ||
101 | |||
102 | for elem in data['nodes']: | ||
103 | node = {} | ||
104 | if 'ipv4' not in elem or 'port' not in elem or 'public_key' not in elem: | ||
105 | print "SKIPPING", elem | ||
106 | continue | ||
107 | |||
108 | if len(elem['public_key']) <> 64: | ||
109 | print "Bad public key %s, skipping!" % elem['public_key'] | ||
110 | continue | ||
111 | |||
112 | node['port'] = int(elem['port']) | ||
113 | node['public_key'] = elem['public_key'] | ||
114 | |||
115 | try: | ||
116 | socket.inet_aton(elem['ipv4']) | ||
117 | node['ipv4'] = elem['ipv4'] | ||
118 | except socket.error: | ||
119 | # IPv4 is not numeric, let's try resolving | ||
120 | try: | ||
121 | print "RESOLVING", elem['ipv4'] | ||
122 | node['ipv4'] = socket.gethostbyname(elem['ipv4']) | ||
123 | except socket.error: | ||
124 | print "Could not resolve ipv4: %s, skipping!" % elem['ipv4'] | ||
125 | continue | ||
126 | |||
127 | if 'status_udp' in elem and elem['status_udp']: | ||
128 | nodes.append(node) | ||
129 | |||
130 | if 'tcp_ports' in elem and elem['tcp_ports'] and \ | ||
131 | 'status_tcp' in elem and elem['status_tcp']: | ||
132 | for port in elem['tcp_ports']: | ||
133 | relay = dict(node) | ||
134 | try: | ||
135 | relay['port'] = int(port) | ||
136 | except ValueError: | ||
137 | continue | ||
138 | |||
139 | tcp_relays.append(relay) | ||
140 | |||
141 | env = jinja2.Environment(loader=Loader()) | ||
142 | env.filters['toxtoc'] = toxtoc | ||
143 | template = env.get_template('tox_bootstrap_template') | ||
144 | tox_bootstrap_h = template.render(nodes=nodes, now=datetime.datetime.now(), json_url=json_url, relays=tcp_relays) | ||
145 | open('tox_bootstrap.h', 'w').write(tox_bootstrap_h) | ||
146 | |||