Browse Source

extend/update documentation

Helge Jung 9 years ago
parent
commit
9d5136b776
3 changed files with 45 additions and 5 deletions
  1. 12 5
      Readme.md
  2. 11 0
      ffstatus/batman.py
  3. 22 0
      ffstatus/server.py

+ 12 - 5
Readme.md

@@ -1,13 +1,12 @@
 # BATCAVE
 
-**B**atman/**A**lfred **T**ransmission **C**ollection, **A**ggregation & **V**alue **E**ngine
+**B**atman / **A**lfred **T**ransmission **C**ollection, **A**ggregation & **V**alue **E**ngine
 
 Dieser Daemon läuft auf einem Rechner der im Freifunk-Mesh hängt
 und fragt periodisch (Default = 15s) die Batman- und Alfred-Daten ab.
 
 Die Daten werden aggregiert und können anschließend an mehrere Datensenken weitergegeben werden:
 * Knoten-Management (allgemeine Meta-Daten zu eigenen Knoten)
-* Redis-Datenbank (zentrale Datenbank mit aktuellen Knoten-Daten)
 * Graphite (Knoten-Graphen und Detail-Statistiken)
 
 Zusätzlich besteht die Möglichkeit der Datenabfrage über eine HTTP-JSON-Schnittstelle.
@@ -30,11 +29,12 @@ sudo update-rc.d ffstatus enable
 ## Nutzung
 
 ```
-$ ./batcave.py -h
-usage: batcave.py [-h] [--logfile LOGFILE] [--interval INTERVAL] [-d] [-n]
-                  [-A ALFRED_JSON] [-B BATADV_VIS] [-G GRAPHITE_HOST]
+usage: batcave.py [-h] [--logfile LOGFILE] [--interval INTERVAL] [-v] [-d]
+                  [-n] [-A ALFRED_JSON] [-B BATADV_VIS] [-G GRAPHITE_HOST]
                   [--graphite-port GRAPHITE_PORT] [--dashing-url DASHING_URL]
                   [--dashing-token DASHING_TOKEN]
+                  [--api-bind-host API_BIND_HOST]
+                  [--api-bind-port API_BIND_PORT] [-S STORAGE_DIR]
 
 Batman/Alfred Transmission Collection, Aggregation & Value Engine
 
@@ -42,6 +42,7 @@ optional arguments:
   -h, --help            show this help message and exit
   --logfile LOGFILE     path for log file
   --interval INTERVAL   data poll interval
+  -v, --verbose         increase output verbosity
   -d, --no-detach       Don't detach (daemonize) ourself
   -n, --no-send         Fetch data but don't send it
   -A ALFRED_JSON, --alfred-json ALFRED_JSON
@@ -56,4 +57,10 @@ optional arguments:
                         Dashing URL
   --dashing-token DASHING_TOKEN
                         Dashing's secret update token
+  --api-bind-host API_BIND_HOST
+                        API-Server Hostname
+  --api-bind-port API_BIND_PORT
+                        API-Server Port
+  -S STORAGE_DIR, --storage-dir STORAGE_DIR
+                        Path where to store data
 ```

+ 11 - 0
ffstatus/batman.py

@@ -19,6 +19,8 @@ class BatmanParser:
 		return 'BatmanParser \'{0}\''.format(self.batadv_vis)
 
 	def sanitycheck(self):
+		"""Checks that batadv-vis is executable and gives sane output."""
+
 		testdata = None
 		try:
 			testdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
@@ -33,23 +35,30 @@ class BatmanParser:
 		return True
 
 	def mac2id(self, mac):
+		"""Derives a nodeid from the given MAC address."""
+
 		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):
+		"""Fetches the current data from batadv-vis and returns it."""
+
 		data = { }
 		ts = int(time.time())
 
+		# call batadv-vis and parse output as JSON
 		rawdata = subprocess.check_output([self.batadv_vis, '-f', 'jsondoc'])
 		batmandata = json.loads(rawdata)
 
+		# dump raw data into file if requested
 		if not batadv_dump is None:
 			jsondata = json.dumps(batmandata, ensure_ascii=False)
 			f = io.open(batadv_dump, 'w')
 			f.write(rawdata)
 			f.close()
 
+		# parse raw data, convert all MAC into nodeid
 		for item in batmandata['vis']:
 			itemid = self.mac2id(item['primary'])
 			aliases = []
@@ -64,6 +73,7 @@ class BatmanParser:
 					#	print('node {0}\'s neighbor {1} has unexpected router {2}'.format(itemid, neighbour['neighbor'], neighbour['router']))
 					neighbours[self.mac2id(neighbour['neighbor'])] = float(neighbour['metric'])
 
+			# construct dict entry as expected by BATCAVE
 			data[itemid] = {
 				'aliases': aliases,
 				'neighbours': neighbours,
@@ -73,6 +83,7 @@ class BatmanParser:
 
 		return data
 
+# standalone test mode
 if __name__ == "__main__":
 	b = BatmanParser()
 	try:

+ 22 - 0
ffstatus/server.py

@@ -20,6 +20,7 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 		BaseHTTPRequestHandler.__init__(self, request, client_address, server)
 
 	def parse_url_pathquery(self):
+		"""Extracts the query parameters from the request path."""
 		url = re.match(r'^/(?P<path>.*?)(\?(?P<query>.+))?$', self.path.strip())
 		if url is None:
 			logging.warn('Failed to parse URL \'' + str(self.path) + '\'.')
@@ -33,23 +34,30 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 		return ( path, query )
 
 	def do_GET(self):
+		"""Handles all HTTP GET requests."""
+
 		path, query = self.parse_url_pathquery()
 		if path is None:
 			self.send_error(400, 'Could not parse URL (' + str(self.path) + ')')
                         return
 
+		# / - index page, shows generic help
 		if path == '':
 			self.respond_index(query)
 			return
 
+		# /list - list stored nodes
 		if path == 'list':
 			self.respond_list(query)
 			return
 
+		# /vpn - notification endpoint for gateway's VPN connections
 		if path == 'vpn':
 			self.respond_vpn(query)
 			return
 
+		# /node/<id>.json - node's data
+		# /node/<id>/field - return specific field from node's data
 		m = re.match(r'node/([a-f0-9]{12})(?P<cmd>\.json|/[a-zA-Z0-9_\-]+)$', path)
 		if m != None:
 			cmd = m.group('cmd')
@@ -59,20 +67,28 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 				self.respond_nodedetail(m.group(1), cmd[1:])
 			return
 
+		# no match -> 404
 		self.send_error(404, 'The URL \'{0}\' was not found here.'.format(path))
 
 	def send_nocache_headers(self):
+		"""Sets HTTP headers indicating that this response shall not be cached."""
+
 		self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
 		self.send_header('Pragma', 'no-cache')
 		self.send_header('Expires', '0')
 
 	def send_headers(self, content_type='text/html; charset=utf-8', nocache=True):
+		"""Send HTTP 200 Response header with the given Content-Type.
+		Optionally send no-caching headers, too."""
+
 		self.send_response(200)
 		self.send_header('Content-Type', content_type)
 		if nocache: self.send_nocache_headers()
 		self.end_headers()
 
 	def respond_index(self, query):
+		"""Display the index page."""
+
 		storage = self.server.storage
 		self.send_headers()
 
@@ -98,6 +114,8 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 		self.wfile.write('</body></html>')
 
 	def respond_list(self, query):
+		"""List stored data."""
+
 		storage = self.server.storage
 		self.send_headers()
 
@@ -127,6 +145,8 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 		self.wfile.write('</table>\n')
 
 	def respond_node(self, nodeid):
+		"""Display node data."""
+
 		storage = self.server.storage
 
 		if nodeid == 'ff00ff00ff00':
@@ -138,10 +158,12 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
 			}))
 			return
 
+		# handle unknown nodes
 		if not nodeid in storage.data:
 			self.send_error(404, 'No node with id \'' + nodeid + '\' present.')
 			return
 
+		# dump node data as JSON
 		self.send_headers('text/json')
 		self.wfile.write(json.dumps(storage.data[nodeid]))