source: genesis/nodes/make-map.py@ 8285

Last change on this file since 8285 was 8285, checked in by rick, 14 years ago

Some serious effort in making it look useable

  • Property svn:executable set to *
File size: 5.6 KB
Line 
1#!/usr/bin/env python
2# vim:ts=2:et:sw=2:ai
3#
4# Build topological network graph
5# Rick van der Zwet <info@rickvanderzwet.nl>
6
7import cgi
8import gformat
9import re
10import sys
11import urllib
12import yaml
13
14def get_yaml(gfile):
15 """ Get configuration yaml for 'item'"""
16 f = open(gfile, 'r')
17 datadump = yaml.load(f)
18 return datadump
19
20def write_yaml(gfile, datadump):
21 """ Write configuration yaml for 'item'"""
22 f = open(gfile, 'w')
23 f.write(yaml.dump(datadump, default_flow_style=False))
24 f.close()
25
26CACHE_FILE = '/tmp/rd2etrs.yaml'
27coordinates = None
28
29def rd2etrs(xrd, yrd, hnap=0.0):
30 """ Convert rd to etrs """
31 global coordinates
32 if coordinates == None:
33 try:
34 coordinates = get_yaml(CACHE_FILE)
35 if coordinates.has_key((xrd, yrd)):
36 return coordinates[(xrd, yrd)]
37 except (IOError,AttributeError):
38 coordinates = dict()
39 pass
40
41 item = dict()
42 item['xrd'] = xrd
43 item['yrd'] = yrd
44 item['hnap'] = hnap
45 f = urllib.urlopen('http://www.rdnap.nl/cgi-bin/rdetrs.pl?func=rd2etrs&xrd=%(xrd)s&yrd=%(yrd)s&hnap=%(hnap)s' % item)
46 raw = f.read()
47
48 r = re.compile('name="([a-z_]+)" value="([0-9\.]+)"')
49 for i in r.finditer(raw):
50 name, value = i.group(1,2)
51 value = float(value)
52 item[name] = value
53
54 lam = item['lam_deg'] + (item['lam_min'] + (item['lam_sec'] / 60)) / 60
55 phi = item['phi_deg'] + (item['phi_min'] + (item['phi_sec'] / 60)) / 60
56 coordinates[(xrd, yrd)] = (phi, lam)
57 write_yaml(CACHE_FILE, coordinates)
58 return (lam, phi)
59
60OUTFILE = 'network.png'
61
62def make_graph():
63 f = open('kmlfile.kml', 'w')
64 f.write("""<?xml version="1.0" encoding="UTF-8"?>
65<kml xmlns="http://earth.google.com/kml/2.0">
66 <Document>
67 <name>WirelessLeiden Nodemap</name>
68 <open>1</open>
69 <description>Generated realtime status of all Wireless Leiden AccessPoints</description>
70 <Style id="node_status_up">
71 <IconStyle>
72 <scale>0.5</scale>
73 <Icon><href>http://www.google.com/mapfiles/kml/paddle/grn-stars-lv.png</href></Icon>
74 </IconStyle>
75 </Style>
76 <Style id="node_status_down">
77 <IconStyle>
78 <scale>0.5</scale>
79 <Icon><href>http://www.google.com/mapfiles/kml/paddle/red-stars-lv.png</href></Icon>
80 </IconStyle>
81 </Style>
82 <Style id="node_status_planned">
83 <IconStyle>
84 <scale>0.5</scale>
85 <Icon><href>http://www.google.com/mapfiles/kml/paddle/wht-stars-lv.png</href></Icon>
86 </IconStyle>
87 </Style>
88 <Folder>
89 <name>Nodes</name>
90 <visibility>0</visibility>
91 <description>All active nodes and links</description>
92 """)
93
94 poel = {}
95 link_type = {}
96 node = {}
97
98 nodes = []
99 links = []
100 try:
101 for host in gformat.get_proxylist() + gformat.get_nodelist():
102 print "## Processing host", host
103 datadump = gformat.get_yaml(host)
104 iface_keys = [elem for elem in datadump.keys() if (elem.startswith('iface_') and not "lo0" in elem)]
105 for iface_key in iface_keys:
106 l = datadump[iface_key]['ip']
107 addr, mask = l.split('/')
108
109 addr = gformat.parseaddr(addr)
110 mask = int(mask)
111 addr = addr & ~((1 << (32 - mask)) - 1)
112 if poel.has_key(addr):
113 poel[addr] += [host]
114 else:
115 poel[addr] = [host]
116 # Assume all eth2wifibridge to be 11a for a moment
117 iface_parent = '_'.join(iface_key.split('_')[0:2])
118 if datadump[iface_parent].has_key('extra_type') and datadump[iface_parent]['extra_type'] == 'eth2wifibridge':
119 link_type[addr] = '11a'
120 else:
121 link_type[addr] = datadump[iface_parent]['type']
122 print "### %s [%s] is of type %s" % (gformat.showaddr(addr), iface_key, link_type[addr])
123 lam, phi = rd2etrs(datadump['rdnap_x'], datadump['rdnap_y'])
124 node[host] = (lam, phi)
125 f.write("""
126 <description>All active nodes</description>
127 <Placemark>
128 <name>Node %(name)s</name>
129 <description>%(desc)s></description>
130 <styleUrl>#node_status_up</styleUrl>
131 <Point><coordinates>%(lam)s,%(phi)s,0</coordinates></Point>
132 </Placemark>
133 """ % {'name' : host, 'desc' : cgi.escape(datadump['location']), 'lam' : lam, 'phi' : phi})
134 nodes += [("POINT(%s, %s)" % (lam, phi))]
135 except (KeyError, ValueError), e:
136 print "[FOUT] in '%s' interface '%s'" % (host,iface_key)
137 raise
138 sys.exit(1)
139
140 f.write("""
141 </Folder>
142 <Folder>
143 <name>Links</name>
144 <visibility>0</visibility>
145 <description>All links</description>
146 """)
147 for addr,leden in poel.iteritems():
148 if link_type[addr] == '11a':
149 color = '#ff0000ff'
150 weight = 2
151 elif link_type[addr] == 'eth':
152 color = '#ffff0000'
153 weight = 4
154 else:
155 color = '#ff000000'
156 weight = 1
157
158 leden = sorted(set(leden))
159 for index,lid in enumerate(leden[:-1]):
160 for buur in leden[index + 1:]:
161 f.write("""
162 <Placemark>
163 <name>%(name)s</name>
164 <visibility>0</visibility>
165 <description>%(desc)s</description>
166 <LineString>
167 <tessellate>0</tessellate>
168 <coordinates> %(lam1)s, %(phi1)s, 0
169 %(lam2)s , %(phi2)s, 0 </coordinates>
170 </LineString>
171 <Style>%(style)s</Style>
172 </Placemark>
173 """ % { 'lam1' : node[lid][0],
174 'phi1' : node[lid][1],
175 'lam2' : node[buur][0],
176 'phi2' : node[buur][1],
177 'name' : "Interlink: %s --- %s" % (lid, buur),
178 'desc' : "%s [%s]" % (gformat.showaddr(addr), link_type[addr]),
179 'style' : "<LineStyle><color>%s</color><width>%s</width></LineStyle>" % (color, weight),
180 })
181 f.write("""
182 </Folder>
183 </Document>
184</kml>
185 """)
186 f.close()
187
188
189if __name__ == "__main__":
190 make_graph()
191
Note: See TracBrowser for help on using the repository browser.