瀏覽代碼

add BATMAN parser

Helge Jung 9 年之前
父節點
當前提交
1f839d1631
共有 3 個文件被更改,包括 104 次插入10 次删除
  1. 5 1
      ffstatus/__init__.py
  2. 81 0
      ffstatus/batman.py
  3. 18 9
      status-daemon.py

+ 5 - 1
ffstatus/__init__.py

@@ -1,10 +1,14 @@
 from copy import deepcopy
 
 from .alfred import AlfredParser
+from .batman import BatmanParser
 from .dashing import DashingClient
 from .graphite import GraphitePush
 
-__all__ = [ 'AlfredParser', 'DashingClient', 'GraphitePush', 'dict_merge' ]
+__all__ = [
+	'AlfredParser', 'BatmanParser',
+	'DashingClient', 'GraphitePush',
+	'dict_merge' ]
 
 def dict_merge(a, b):
     '''recursively merges dict's. not just simple a['key'] = b['key'], if

+ 81 - 0
ffstatus/batman.py

@@ -0,0 +1,81 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+from copy import deepcopy
+import io
+import json
+import socket
+import subprocess
+import time
+
+import string
+import StringIO
+
+class BatmanParser:
+	batadv_vis = 'batadv_vis'
+	mactranslation = string.maketrans('2367abef', '014589cd')
+
+	def sanitycheck(self):
+		testdata = None
+		try:
+			testdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
+		except Exception as err:
+			raise Exception("batadv_vis not found or incompatible: " + str(err))
+
+		try:
+			check = json.loads(testdata)
+		except Exception as err:
+			raise Exception("batadv_vis does not return valid JSON data: " + str(err))
+
+		return True
+
+	def mac2id(self, mac):
+		temp = str(mac.lower().replace(':', ''))
+#		temp = temp[0] + temp[1].translate(self.mactranslation) + temp[2:]
+		return temp
+
+	def fetch(self, batadv_dump=None, include_rawdata=False):
+		data = { }
+		ts = int(time.time())
+
+		rawdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
+		batmandata = json.loads(rawdata)
+
+		if not batadv_dump is None:
+			jsondata = json.dumps(batmandata, ensure_ascii=False)
+			f = io.open(batadv_dump, 'w')
+			f.write(rawdata)
+			f.close()
+
+		for item in batmandata['vis']:
+			itemid = self.mac2id(item['primary'])
+			aliases = []
+			if 'secondary' in item:
+				for mac in item['secondary']:
+					aliases.append(self.mac2id(mac))
+
+			neighbours = {}
+			if 'neighbors' in item:
+				for neighbour in item['neighbors']:
+					if neighbour['router'] != item['primary']:
+						#print('node {0}\'s neighbor {1} has unexpected router {2}'.format(itemid, neighbour['neighbor'], neighbour['router']))
+						neighbours[self.mac2id(neighbour['neighbor'])] = float(neighbour['metric'])
+
+			data[itemid] = {
+				'aliases': aliases,
+				'neighbours': neighbours,
+				'clients': [ self.mac2id(x) for x in item['clients'] ] if 'clients' in item else [],
+			}
+
+		return data
+
+if __name__ == "__main__":
+	b = BatmanParser()
+	try:
+		b.sanitycheck()
+	except Exception  as err:
+		print('SANITY-CHECK failed:', str(err))
+		import sys
+		sys.exit(1)
+	data = b.fetch()
+	print(json.dumps(data))

+ 18 - 9
status-daemon.py

@@ -22,31 +22,40 @@ logger.addHandler(fh)
 logger.info('Starting up')
 
 a = AlfredParser()
+b = BatmanParser()
 d = DashingClient('dashing.krombel.de', 'TODO')
 g = GraphitePush('fdca:ffee:ff12:a254::da7a', 2003)
 data = { }
 
 if DUMMY_MODE:
-	a.alfred_json = '/home/ffpb-statusbot/status-daemon/alfred-json'
+	import os
+	mydir = os.path.realpath(os.path.dirname(__file__))
+	a.alfred_json = os.path.join(mydir, 'alfred-json')
+	print('DUMMY.a =', a.alfred_json)
+	b.batadv_vis = os.path.join(mydir, 'batadv_vis')
+	print('DUMMY.b =', b.batadv_vis)
 	g.dont_send = True
 
-try:
-	a.sanitycheck()
-except Exception as err:
-	logger.critical('AlfredParser.sanitycheck() failed: ' + str(err))
-	print('FAILED SANITY CHECK: ' + str(err))
-	sys.exit(1)
+for i in [ ('AlfredParser', a), ('BatmanParser', b) ]:
+	try:
+		i[1].sanitycheck()
+	except Exception as err:
+		logger.critical(i[0] + '.sanitycheck() failed: ' + str(err))
+		print('FAILED SANITY CHECK: ' + str(err))
+		sys.exit(1)
 
 daemon_context = daemon.DaemonContext(
 	files_preserve = [ fh.stream ],
 )
 with daemon_context:
-
 	while True:
 		try:
 			ts = int(time.time())
 			logger.debug('Step 1/3: Fetching data ...')
-			newdata = a.fetch()
+			alfreddata = a.fetch()
+			batmandata = b.fetch()
+			newdata = dict_merge(alfreddata, batmandata)
+			logger.info('Fetched data: {0} ALFRED with {1} BATMAN makes {2} total'.format(len(alfreddata), len(batmandata), len(newdata)))
 
 			logger.debug('Step 2/3: Pushing update data ...')
 			graphitedata = g.push(newdata, ts=ts)