#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from storage import Storage
import json
import re
from SocketServer import ThreadingMixIn
class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
url = self.path
if url == '/':
self.respond_index()
return
if url == '/list':
self.respond_list()
return
m = re.match(r'^/node/([a-f0-9]{12})\.json$', url)
if m != None:
self.respond_node(m.group(1))
return
self.send_error(404, 'The URL \'{0}\' was not found here.'.format(url))
def send_nocache_headers(self):
self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
self.send_header('Pragma', 'no-cache')
self.send_header('Expires', '0')
def respond_index(self):
storage = self.server.storage
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_nocache_headers()
self.end_headers()
self.wfile.write('
BATCAVE\n')
self.wfile.write('\n')
self.wfile.write('BATCAVE
\n')
self.wfile.write('Dies ist ein interner Hintergrund-Dienst. Er wird nur von anderen Diensten\n')
self.wfile.write('angesprochen und sollte aus einer Mehrzahl von Gründen nicht öffentlich\n')
self.wfile.write('zugänglich sein.
\n')
self.wfile.write('Status
\n')
self.wfile.write('Daten: ')
self.wfile.write(len(storage.data))
self.wfile.write('\n')
self.wfile.write('API
\n')
self.wfile.write('Grundsätzlich ist das Antwort-Format JSON und alle Daten sind Live-Daten (kein Cache) die ggf. etwas Bearbeitungs-Zeit erfordern.
')
self.wfile.write('\n')
self.wfile.write('- nodes.json
- zur Verwendung mit ffmap (MACs anonymisiert)
\n')
self.wfile.write('- /node/<id>.json
- alle vorhandenen Information zu der gewünschten Node
\n')
self.wfile.write('
\n')
self.wfile.write('')
def respond_list(self):
storage = self.server.storage
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_nocache_headers()
self.end_headers()
self.wfile.write('BATCAVE\n')
self.wfile.write('\n')
self.wfile.write('BATCAVE - LIST
\n')
self.wfile.write('\n')
self.wfile.write('ID | Name |
\n')
self.wfile.write('\n')
for nodeid in storage.data:
nodename = storage.data[nodeid]['hostname'] if 'hostname' in storage.data[nodeid] else '<?>'
self.wfile.write('' + nodeid + ' | ' + nodename + ' |
')
self.wfile.write('\n')
self.wfile.write('
\n')
def respond_node(self, nodeid):
storage = self.server.storage
if nodeid == 'ff00ff00ff00':
self.send_response(200)
self.send_header('Content-Type', 'text/json')
self.send_nocache_headers()
self.end_headers()
self.wfile.write(json.dumps({
'name': 'API-Example',
'nodeid': nodeid,
'META': 'Dies ist ein minimaler Beispiel-Datensatz. Herzlichen Glückwunsch, du hast das Prinzip der API kapiert.',
}))
return
if not nodeid in storage.data:
self.send_error(404, 'No node with id \'' + nodeid + '\' present.')
return
self.send_response(200)
self.send_header('Content-Type', 'text/json')
self.send_nocache_headers()
self.end_headers()
self.wfile.write(json.dumps(storage.data[nodeid]))
class ApiServer(ThreadingMixIn, HTTPServer):
def __init__(self, endpoint, storage):
HTTPServer.__init__(self, endpoint, BatcaveHttpRequestHandler)
self.storage = storage
def __str__(self):
return 'ApiServer on {0}'.format(self.server_address)
if __name__ == '__main__':
dummystorage = Storage()
server = ApiServer(('0.0.0.0', 8888), dummystorage)
print("Server:", str(server))
server.serve_forever()