generate_tox_bootstrap.py 3.9 KB

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