python3 updates
This commit is contained in:
332
nandod
332
nandod
@@ -1,140 +1,197 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import SocketServer,threading
|
||||
import socketserver, threading
|
||||
import sqlite3
|
||||
import time,os,sys
|
||||
import time, os, sys
|
||||
|
||||
ALIVE = 60 * 30
|
||||
TABLE_HEAD = "Host|IP|Age(d h:m:s)|Description\n"
|
||||
|
||||
ALIVE=60*30
|
||||
TABLE_HEAD="Host|IP|Age(d h:m:s)|Description\n"
|
||||
|
||||
def setup_options():
|
||||
''' Setup the command line options '''
|
||||
""" Setup the command line options """
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser=ArgumentParser(description="Alive notifier.")
|
||||
parser.add_argument("--host",action='store', dest='HOST',default='0.0.0.0',type=str,
|
||||
help="Bind to address: %(default)s")
|
||||
parser.add_argument("--port", action='store', dest='PORT', default=13370,type=int,
|
||||
help="Bind to port: %(default)s")
|
||||
parser.add_argument("--html-port", action='store', dest='WEBPORT', default=13370,type=int,
|
||||
help="Bind www server to port. 0 to disable, default: %(default)s")
|
||||
parser.add_argument("--db",action='store', dest='DB',default='/tmp/nando.sqlite',type=str,
|
||||
help="Sqlite file for database: %(default)s")
|
||||
parser.add_argument("--quiet","-q",action='store_true', dest='quiet',default=False,
|
||||
help="Quiet operation: %(default)s")
|
||||
options=parser.parse_args()
|
||||
parser = ArgumentParser(description="Alive notifier.")
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
action="store",
|
||||
dest="HOST",
|
||||
default="0.0.0.0",
|
||||
type=str,
|
||||
help="Bind to address: %(default)s",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
action="store",
|
||||
dest="PORT",
|
||||
default=13370,
|
||||
type=int,
|
||||
help="Bind to port: %(default)s",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--html-port",
|
||||
action="store",
|
||||
dest="WEBPORT",
|
||||
default=13370,
|
||||
type=int,
|
||||
help="Bind www server to port. 0 to disable, default: %(default)s",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--db",
|
||||
action="store",
|
||||
dest="DB",
|
||||
default="/tmp/nando.sqlite",
|
||||
type=str,
|
||||
help="Sqlite file for database: %(default)s",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--quiet",
|
||||
"-q",
|
||||
action="store_true",
|
||||
dest="quiet",
|
||||
default=False,
|
||||
help="Quiet operation: %(default)s",
|
||||
)
|
||||
options = parser.parse_args()
|
||||
return options
|
||||
|
||||
|
||||
class UDPHandler(SocketServer.BaseRequestHandler):
|
||||
class UDPHandler(socketserver.BaseRequestHandler):
|
||||
def handle(self):
|
||||
data = self.request[0].strip()
|
||||
DB = DataBase(opts.DB)
|
||||
data = self.request[0].decode("utf-8").strip()
|
||||
socket = self.request[1]
|
||||
if not opts.quiet:
|
||||
print "{0} wrote: {1}".format(self.client_address[0],data)
|
||||
if data=="list":
|
||||
reply=DB.list_all()
|
||||
elif data=="alive":
|
||||
reply=DB.list_alive()
|
||||
elif data=="lost":
|
||||
reply=DB.list_lost()
|
||||
print(("{0} wrote: {1}".format(self.client_address[0], data)))
|
||||
if data == "list":
|
||||
reply = DB.list_all()
|
||||
elif data == "alive":
|
||||
reply = DB.list_alive()
|
||||
elif data == "lost":
|
||||
reply = DB.list_lost()
|
||||
else:
|
||||
DB.update(data)
|
||||
reply="OK"
|
||||
socket.sendto(reply, self.client_address)
|
||||
reply = "OK"
|
||||
socket.sendto(reply.encode("utf-8"), self.client_address)
|
||||
DB.close()
|
||||
|
||||
class TCPHandler(SocketServer.BaseRequestHandler):
|
||||
|
||||
class TCPHandler(socketserver.BaseRequestHandler):
|
||||
def handle(self):
|
||||
HTMLDB = DataBase(opts.DB)
|
||||
if not opts.quiet:
|
||||
print "TCP request: {0}".format(self.client_address[0])
|
||||
self.data = self.request.recv(1024).strip()
|
||||
print(("TCP request: {0}".format(self.client_address[0])))
|
||||
self.data = self.request.recv(1024).decode("utf-8").strip()
|
||||
method, path, _ = self.data.splitlines()[0].split()
|
||||
self.path = path.lstrip("/")
|
||||
self.request.send('HTTP/1.0 200 OK\r\n')
|
||||
self.request.send("Content-Type: text/html\r\n\r\n")
|
||||
self.request.sendall(HTMLDB.HTML_list(self.path))
|
||||
self.request.send(b"HTTP/1.0 200 OK\r\n")
|
||||
self.request.send(b"Content-Type: text/html\r\n\r\n")
|
||||
self.request.sendall(HTMLDB.HTML_list(self.path).encode("utf-8"))
|
||||
self.request.close()
|
||||
HTMLDB.close()
|
||||
|
||||
|
||||
class DataBase:
|
||||
def __init__(self,DB):
|
||||
self.DBfile=DB
|
||||
self.conn=None
|
||||
self.db=None
|
||||
def __init__(self, DB):
|
||||
self.DBfile = DB
|
||||
self.conn = None
|
||||
self.db = None
|
||||
if not os.path.exists(self.DBfile):
|
||||
self.createDB()
|
||||
self.conn_init()
|
||||
|
||||
def close(self):
|
||||
self.conn.close()
|
||||
|
||||
def conn_init(self):
|
||||
self.conn=sqlite3.connect(self.DBfile)
|
||||
self.db=self.conn.cursor()
|
||||
self.conn.text_factory=str
|
||||
self.conn = sqlite3.connect(self.DBfile)
|
||||
self.db = self.conn.cursor()
|
||||
self.conn.text_factory = str
|
||||
|
||||
def conn_end(self):
|
||||
self.conn.commit()
|
||||
#self.conn.close()
|
||||
# self.conn.close()
|
||||
|
||||
def createDB(self):
|
||||
self.conn_init()
|
||||
self.db.execute('CREATE TABLE alive (id TEXT PRIMARY KEY,\
|
||||
self.db.execute(
|
||||
"CREATE TABLE alive (id TEXT PRIMARY KEY,\
|
||||
ip TEXT,\
|
||||
desc TEXT,\
|
||||
date INTEGER)')
|
||||
date INTEGER)"
|
||||
)
|
||||
self.conn_end()
|
||||
|
||||
def update(self,id):
|
||||
def update(self, id):
|
||||
try:
|
||||
host,ip,desc=id.split("|",3)
|
||||
desc=''.join([ c for c in desc if c not in ['\n','\r','|'] ])
|
||||
if len(ip.split("."))!=4:
|
||||
host, ip, desc = id.split("|", 3)
|
||||
desc = "".join([c for c in desc if c not in ["\n", "\r", "|"]])
|
||||
if len(ip.split(".")) != 4:
|
||||
return 1
|
||||
except:
|
||||
return
|
||||
self.db=self.conn.cursor()
|
||||
self.db = self.conn.cursor()
|
||||
if desc is "":
|
||||
self.db.execute("INSERT OR REPLACE INTO alive(id,ip,date) \
|
||||
VALUES(?,?,?)",(host,ip,int(time.time())))
|
||||
self.db.execute(
|
||||
"INSERT OR REPLACE INTO alive(id,ip,date) \
|
||||
VALUES(?,?,?)",
|
||||
(host, ip, int(time.time())),
|
||||
)
|
||||
else:
|
||||
self.db.execute("INSERT OR REPLACE INTO alive(id,ip,date,desc) \
|
||||
VALUES(?,?,?,?)",(host,ip,int(time.time()),desc))
|
||||
self.db.execute(
|
||||
"INSERT OR REPLACE INTO alive(id,ip,date,desc) \
|
||||
VALUES(?,?,?,?)",
|
||||
(host, ip, int(time.time()), desc),
|
||||
)
|
||||
self.conn_end()
|
||||
|
||||
def list_all(self):
|
||||
self.db=self.conn.cursor()
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY id")
|
||||
alive=[]
|
||||
lost=[]
|
||||
self.db = self.conn.cursor()
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY date DESC")
|
||||
alive = []
|
||||
lost = []
|
||||
for row in self.db:
|
||||
age=int(time.time())-row[2]
|
||||
if age<ALIVE:
|
||||
alive.append("{0}|{1}|{2}|{3}".format(row[0],row[1], humanize_time(age),row[3]))
|
||||
age = int(time.time()) - row[2]
|
||||
if age < ALIVE:
|
||||
alive.append(
|
||||
"{0}|{1}|{2}|{3}".format(row[0], row[1], humanize_time(age), row[3])
|
||||
)
|
||||
else:
|
||||
lost.append( "{0}|{1}|{2}|{3}".format(row[0],row[1], humanize_time(age),row[3]))
|
||||
return TABLE_HEAD+"\n".join(alive)+"\n---|---|---|---\n"+"\n".join(lost)
|
||||
lost.append(
|
||||
"{0}|{1}|{2}|{3}".format(row[0], row[1], humanize_time(age), row[3])
|
||||
)
|
||||
return TABLE_HEAD + "\n".join(alive) + "\n---|---|---|---\n" + "\n".join(lost)
|
||||
|
||||
def list_alive(self):
|
||||
self.db=self.conn.cursor()
|
||||
self.db = self.conn.cursor()
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY date DESC")
|
||||
msg=[]
|
||||
msg = []
|
||||
for row in self.db:
|
||||
age=int(time.time())-row[2]
|
||||
if age<ALIVE:
|
||||
msg.append("{0}|{1}|{2}|{3}".format(row[0],row[1], humanize_time(age),row[3]))
|
||||
return TABLE_HEAD+"\n".join(msg)
|
||||
age = int(time.time()) - row[2]
|
||||
if age < ALIVE:
|
||||
msg.append(
|
||||
"{0}|{1}|{2}|{3}".format(row[0], row[1], humanize_time(age), row[3])
|
||||
)
|
||||
return TABLE_HEAD + "\n".join(msg)
|
||||
|
||||
def list_lost(self):
|
||||
self.db=self.conn.cursor()
|
||||
self.db = self.conn.cursor()
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY date")
|
||||
msg=[]
|
||||
msg = []
|
||||
for row in self.db:
|
||||
age=int(time.time())-row[2]
|
||||
if age>=ALIVE:
|
||||
msg.append("{0}|{1}|{2}|{3}".format(row[0],row[1], humanize_time(age),row[3]))
|
||||
return TABLE_HEAD+"\n".join(msg)
|
||||
age = int(time.time()) - row[2]
|
||||
if age >= ALIVE:
|
||||
msg.append(
|
||||
"{0}|{1}|{2}|{3}".format(row[0], row[1], humanize_time(age), row[3])
|
||||
)
|
||||
return TABLE_HEAD + "\n".join(msg)
|
||||
|
||||
def HTML_list(self, name):
|
||||
# name = '' means do not filter by name
|
||||
msg=[]
|
||||
msg.append('''<html>
|
||||
msg = []
|
||||
msg.append(
|
||||
"""<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
@@ -153,78 +210,115 @@ td, th {
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><h1>Alive</h1><table>''')
|
||||
self.db=self.conn.cursor()
|
||||
<body><h1>Alive</h1><table>"""
|
||||
)
|
||||
self.db = self.conn.cursor()
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY id")
|
||||
msg.append('<tr><th>{0}</th><th>{1}</th><th class="right">{2}</th><th>{3}</th></tr>'.format('Host','IP','Age[d h:m:s]','Description'))
|
||||
msg.append(
|
||||
'<tr><th>{0}</th><th>{1}</th><th class="right">{2}</th><th>{3}</th></tr>'.format(
|
||||
"Host", "IP", "Age[d h:m:s]", "Description"
|
||||
)
|
||||
)
|
||||
for row in self.db:
|
||||
if name != '':
|
||||
if name != "":
|
||||
if name != row[0]:
|
||||
continue
|
||||
age=int(time.time())-row[2]
|
||||
age = int(time.time()) - row[2]
|
||||
if age < ALIVE:
|
||||
msg.append('<tr><td>{0}</td><td>{1}</td><td class="right">{2}</td><td>{3}</td></tr>'.format(row[0],row[1],humanize_time(age),row[3]))
|
||||
msg.append('</table><h1>Lost</h1><table>')
|
||||
msg.append('<tr><th>{0}</th><th>{1}</th><th class="right">{2}</th><th>{3}</th></tr>'.format('Host','IP','Age[d h:m:s]','Description'))
|
||||
msg.append(
|
||||
'<tr><td>{0}</td><td>{1}</td><td class="right">{2}</td><td>{3}</td></tr>'.format(
|
||||
row[0], row[1], humanize_time(age), row[3]
|
||||
)
|
||||
)
|
||||
msg.append("</table><h1>Lost</h1><table>")
|
||||
msg.append(
|
||||
'<tr><th>{0}</th><th>{1}</th><th class="right">{2}</th><th>{3}</th></tr>'.format(
|
||||
"Host", "IP", "Age[d h:m:s]", "Description"
|
||||
)
|
||||
)
|
||||
self.db.execute("SELECT id,ip,date,desc FROM alive ORDER BY id")
|
||||
for row in self.db:
|
||||
if name != '':
|
||||
if name != "":
|
||||
if name != row[0]:
|
||||
continue
|
||||
age=int(time.time())-row[2]
|
||||
age = int(time.time()) - row[2]
|
||||
if age >= ALIVE:
|
||||
msg.append('<tr><td>{0}</td><td>{1}</td><td class="right">{2}</td><td>{3}</td></tr>'.format(row[0],row[1],humanize_time(age),row[3]))
|
||||
msg.append('</table></body></html>')
|
||||
msg.append(
|
||||
'<tr><td>{0}</td><td>{1}</td><td class="right">{2}</td><td>{3}</td></tr>'.format(
|
||||
row[0], row[1], humanize_time(age), row[3]
|
||||
)
|
||||
)
|
||||
msg.append("</table></body></html>")
|
||||
|
||||
return "\n\r".join(msg)
|
||||
|
||||
def UDPserve():
|
||||
global DB
|
||||
global server
|
||||
DB=DataBase(opts.DB)
|
||||
server = SocketServer.UDPServer((opts.HOST, opts.PORT), UDPHandler)
|
||||
server.serve_forever()
|
||||
def TCPserve():
|
||||
global HTMLDB
|
||||
global HTMLserver
|
||||
time.sleep(2)
|
||||
try:
|
||||
HTMLDB=DataBase(opts.DB)
|
||||
HTMLserver = SocketServer.TCPServer((opts.HOST, opts.WEBPORT), TCPHandler)
|
||||
HTMLserver.serve_forever()
|
||||
except:
|
||||
sys.exit(1)
|
||||
class UDPServe:
|
||||
def __init__(self, opts):
|
||||
self.server = socketserver.UDPServer((opts.HOST, opts.PORT), UDPHandler)
|
||||
|
||||
def start(self):
|
||||
thread = threading.Thread(target=self.serve)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
def serve(self):
|
||||
self.server.serve_forever()
|
||||
|
||||
def stop(self):
|
||||
self.server.shutdown()
|
||||
self.server.server_close()
|
||||
|
||||
|
||||
class TCPServe:
|
||||
def __init__(self, opts):
|
||||
self.server = socketserver.TCPServer((opts.HOST, opts.WEBPORT), TCPHandler)
|
||||
|
||||
def start(self):
|
||||
thread = threading.Thread(target=self.serve)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
def serve(self):
|
||||
time.sleep(2)
|
||||
self.server.serve_forever()
|
||||
|
||||
def stop(self):
|
||||
self.server.shutdown()
|
||||
self.server.server_close()
|
||||
|
||||
|
||||
|
||||
def humanize_time(secs):
|
||||
mins, secs = divmod(secs, 60)
|
||||
hours, mins = divmod(mins, 60)
|
||||
if hours < 24:
|
||||
return '%02d:%02d:%02d' % (hours, mins, secs)
|
||||
return "%02d:%02d:%02d" % (hours, mins, secs)
|
||||
else:
|
||||
days, hours = divmod(hours, 24)
|
||||
return '%dd %02d:%02d:%02d' % (days, hours, mins, secs)
|
||||
return "%dd %02d:%02d:%02d" % (days, hours, mins, secs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
opts=setup_options()
|
||||
opts = setup_options()
|
||||
if not opts.quiet:
|
||||
print("Starting NandoD UDP:{0}:{1}, TCP:{0}:{2}".format(
|
||||
opts.HOST,
|
||||
opts.PORT,
|
||||
opts.WEBPORT
|
||||
))
|
||||
UDP=threading.Thread(target=UDPserve)
|
||||
UDP.daemon=True
|
||||
print(
|
||||
(
|
||||
"Starting NandoD UDP:{0}:{1}, TCP:{0}:{2}".format(
|
||||
opts.HOST, opts.PORT, opts.WEBPORT
|
||||
)
|
||||
)
|
||||
)
|
||||
UDP = UDPServe(opts)
|
||||
UDP.start()
|
||||
if opts.WEBPORT > 0:
|
||||
TCP=threading.Thread(target=TCPserve)
|
||||
TCP.daemon=True
|
||||
TCP = TCPServe(opts)
|
||||
TCP.start()
|
||||
while True:
|
||||
try:
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
print("Exiting..")
|
||||
server.shutdown()
|
||||
UDP.stop()
|
||||
if opts.WEBPORT > 0:
|
||||
HTMLserver.shutdown()
|
||||
TCP.stop()
|
||||
sys.exit(0)
|
||||
|
||||
Reference in New Issue
Block a user