summaryrefslogtreecommitdiff
path: root/generate_tox_bootstrap.py
diff options
context:
space:
mode:
Diffstat (limited to 'generate_tox_bootstrap.py')
-rw-r--r--generate_tox_bootstrap.py146
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
4import datetime
5import jinja2
6import json
7import requests
8import socket
9
10json_url = 'https://nodes.tox.chat/json'
11
12tox_bootstrap_template = """
13/*
14 * Generated with generate_tox_bootstrap.py by GDR!
15 * from {{ json_url }} on {{ now }}
16 */
17struct 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
41struct 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
62def 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
89class Loader(jinja2.BaseLoader):
90 def get_source(self, environment, template):
91 return tox_bootstrap_template, 'tox_bootstrap_template', True
92
93if __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