mirror of
https://github.com/cwinfo/yggdrasil-map
synced 2024-11-09 16:00:27 +00:00
150 lines
3.4 KiB
Python
Executable File
150 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
cjdns_path = '/home/antti/prog/cjdns/'
|
|
|
|
import sys
|
|
sys.path.append(cjdns_path + 'contrib/python/cjdnsadmin/')
|
|
import adminTools as admin
|
|
from collections import deque
|
|
import pygraphviz as pgv
|
|
import json
|
|
import time
|
|
import httplib2
|
|
|
|
|
|
cjdns = admin.connect()
|
|
root = admin.whoami(cjdns)
|
|
rootIP = root['IP']
|
|
|
|
G = pgv.AGraph(strict=True, directed=False, size='10!')
|
|
G.add_node(rootIP, label=rootIP[-4:])
|
|
|
|
nodes = deque()
|
|
nodes.append(rootIP)
|
|
|
|
while len(nodes) != 0:
|
|
parentIP = nodes.popleft()
|
|
resp = cjdns.NodeStore_nodeForAddr(parentIP)
|
|
numLinks = 0
|
|
|
|
if 'result' in resp:
|
|
link = resp['result']
|
|
if 'linkCount' in link:
|
|
numLinks = int(resp['result']['linkCount'])
|
|
G.get_node(parentIP).attr['version'] = resp['result']['protocolVersion']
|
|
|
|
for i in range(0, numLinks):
|
|
resp = cjdns.NodeStore_getLink(parentIP, i)
|
|
childLink = resp['result']
|
|
childIP = childLink['child']
|
|
|
|
# Check to see if its one hop away from parent node
|
|
if childLink['isOneHop'] != 1:
|
|
continue
|
|
|
|
# If its a new node then we want to follow it
|
|
if not childIP in G.nodes():
|
|
G.add_node(childIP, label=childIP[-4:])
|
|
G.get_node(childIP).attr['version'] = 0
|
|
nodes.append(childIP)
|
|
|
|
# If there is not a link between the nodes we should put one there
|
|
if not G.has_edge(childIP, parentIP):
|
|
G.add_edge(parentIP, childIP, len=1.0)
|
|
|
|
print 'Number of nodes:', G.number_of_nodes()
|
|
print 'Number of edges:', G.number_of_edges()
|
|
|
|
G.layout(prog='neato', args='-Gepsilon=0.0001 -Gmaxiter=100000') # neato, fdp, dot
|
|
|
|
|
|
max_neighbors = 0
|
|
|
|
for n in G.iternodes():
|
|
neighbors = len(G.neighbors(n))
|
|
if neighbors > max_neighbors:
|
|
max_neighbors = neighbors
|
|
|
|
print 'Max neighbors:', max_neighbors
|
|
|
|
|
|
|
|
def download_node_names():
|
|
print "Downloading names"
|
|
page = 'http://[fc5d:baa5:61fc:6ffd:9554:67f0:e290:7535]/nodes/list.json'
|
|
|
|
ip_dict = dict()
|
|
h = httplib2.Http(".cache", timeout=15.0)
|
|
try:
|
|
r, content = h.request(page, "GET")
|
|
nameip = json.loads(content)['nodes']
|
|
|
|
for node in nameip:
|
|
ip_dict[node['ip']] = node['name']
|
|
|
|
print "Names downloaded"
|
|
except Exception as e:
|
|
print "Connection to Mikey's nodelist failed, continuing without names", e
|
|
|
|
return ip_dict
|
|
|
|
|
|
node_names = download_node_names()
|
|
|
|
def gradient_color(ratio, colors):
|
|
jump = 1.0 / (len(colors) - 1)
|
|
gap_num = int(ratio / (jump + 0.0000001))
|
|
|
|
a = colors[gap_num]
|
|
b = colors[gap_num + 1]
|
|
|
|
ratio = (ratio - gap_num * jump) * (len(colors) - 1)
|
|
|
|
r = a[0] + (b[0] - a[0]) * ratio
|
|
g = a[1] + (b[1] - a[1]) * ratio
|
|
b = a[2] + (b[2] - a[2]) * ratio
|
|
|
|
return '#%02x%02x%02x' % (r, g, b)
|
|
|
|
|
|
out_data = {
|
|
'created': int(time.time()),
|
|
'nodes': [],
|
|
'edges': []
|
|
}
|
|
|
|
for n in G.iternodes():
|
|
neighbor_ratio = len(G.neighbors(n)) / float(max_neighbors)
|
|
|
|
pos = n.attr['pos'].split(',', 1)
|
|
|
|
try:
|
|
name = node_names[n.name]
|
|
except:
|
|
name = n.attr['label']
|
|
|
|
out_data['nodes'].append({
|
|
'id': n.name,
|
|
'label': name,
|
|
'version': n.attr['version'],
|
|
'x': float(pos[0]),
|
|
'y': float(pos[1]),
|
|
# 'color': gradient_color(neighbor_ratio, [(255,60,20), (23,255,84), (41,187,255)]),
|
|
'color': gradient_color(neighbor_ratio, [(100, 100, 100), (0, 0, 0)]),
|
|
# 'color': gradient_color(neighbor_ratio, [(255, 255, 255), (255, 0 ,255)]),
|
|
'size': neighbor_ratio
|
|
})
|
|
|
|
# '#29BBFF', '#17FF54', '#FFBD0F', '#FF3C14', '#590409'
|
|
|
|
for e in G.iteredges():
|
|
out_data['edges'].append({
|
|
'sourceID': e[0],
|
|
'targetID': e[1]
|
|
})
|
|
|
|
json_output = json.dumps(out_data)
|
|
|
|
f = open('web/static/graph.json', 'w')
|
|
f.write(json_output)
|
|
f.close() |