mirror of
https://github.com/craigerl/aprsd.git
synced 2024-10-31 15:07:13 -04:00
Admin UI working again
This commit is contained in:
parent
333feee805
commit
0ca9072c97
@ -96,12 +96,14 @@ def server(ctx, flush):
|
|||||||
packets.PacketTrack().flush()
|
packets.PacketTrack().flush()
|
||||||
packets.WatchList().flush()
|
packets.WatchList().flush()
|
||||||
packets.SeenList().flush()
|
packets.SeenList().flush()
|
||||||
|
packets.PacketList().flush()
|
||||||
else:
|
else:
|
||||||
# Try and load saved MsgTrack list
|
# Try and load saved MsgTrack list
|
||||||
LOG.debug("Loading saved MsgTrack object.")
|
LOG.debug("Loading saved MsgTrack object.")
|
||||||
packets.PacketTrack().load()
|
packets.PacketTrack().load()
|
||||||
packets.WatchList().load()
|
packets.WatchList().load()
|
||||||
packets.SeenList().load()
|
packets.SeenList().load()
|
||||||
|
packets.PacketList().load()
|
||||||
|
|
||||||
keepalive = keep_alive.KeepAliveThread()
|
keepalive = keep_alive.KeepAliveThread()
|
||||||
keepalive.start()
|
keepalive.start()
|
||||||
|
@ -96,6 +96,7 @@ def signal_handler(sig, frame):
|
|||||||
packets.PacketTrack().save()
|
packets.PacketTrack().save()
|
||||||
packets.WatchList().save()
|
packets.WatchList().save()
|
||||||
packets.SeenList().save()
|
packets.SeenList().save()
|
||||||
|
packets.PacketList().save()
|
||||||
LOG.info(collector.Collector().collect())
|
LOG.info(collector.Collector().collect())
|
||||||
# signal.signal(signal.SIGTERM, sys.exit(0))
|
# signal.signal(signal.SIGTERM, sys.exit(0))
|
||||||
# sys.exit(0)
|
# sys.exit(0)
|
||||||
|
@ -7,24 +7,27 @@ from oslo_config import cfg
|
|||||||
import wrapt
|
import wrapt
|
||||||
|
|
||||||
from aprsd.packets import seen_list
|
from aprsd.packets import seen_list
|
||||||
|
from aprsd.utils import objectstore
|
||||||
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger("APRSD")
|
LOG = logging.getLogger("APRSD")
|
||||||
|
|
||||||
|
|
||||||
class PacketList(MutableMapping):
|
class PacketList(MutableMapping, objectstore.ObjectStoreMixin):
|
||||||
_instance = None
|
_instance = None
|
||||||
lock = threading.Lock()
|
lock = threading.Lock()
|
||||||
_total_rx: int = 0
|
_total_rx: int = 0
|
||||||
_total_tx: int = 0
|
_total_tx: int = 0
|
||||||
types = {}
|
|
||||||
|
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
cls._instance = super().__new__(cls)
|
cls._instance = super().__new__(cls)
|
||||||
cls._maxlen = 100
|
cls._maxlen = 100
|
||||||
cls.d = OrderedDict()
|
cls.data = {
|
||||||
|
"types": {},
|
||||||
|
"packets": OrderedDict(),
|
||||||
|
}
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
@ -33,9 +36,9 @@ class PacketList(MutableMapping):
|
|||||||
self._total_rx += 1
|
self._total_rx += 1
|
||||||
self._add(packet)
|
self._add(packet)
|
||||||
ptype = packet.__class__.__name__
|
ptype = packet.__class__.__name__
|
||||||
if not ptype in self.types:
|
if not ptype in self.data["types"]:
|
||||||
self.types[ptype] = {"tx": 0, "rx": 0}
|
self.data["types"][ptype] = {"tx": 0, "rx": 0}
|
||||||
self.types[ptype]["rx"] += 1
|
self.data["types"][ptype]["rx"] += 1
|
||||||
seen_list.SeenList().update_seen(packet)
|
seen_list.SeenList().update_seen(packet)
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
@ -44,9 +47,9 @@ class PacketList(MutableMapping):
|
|||||||
self._total_tx += 1
|
self._total_tx += 1
|
||||||
self._add(packet)
|
self._add(packet)
|
||||||
ptype = packet.__class__.__name__
|
ptype = packet.__class__.__name__
|
||||||
if not ptype in self.types:
|
if not ptype in self.data["types"]:
|
||||||
self.types[ptype] = {"tx": 0, "rx": 0}
|
self.data["types"][ptype] = {"tx": 0, "rx": 0}
|
||||||
self.types[ptype]["tx"] += 1
|
self.data["types"][ptype]["tx"] += 1
|
||||||
seen_list.SeenList().update_seen(packet)
|
seen_list.SeenList().update_seen(packet)
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
@ -54,7 +57,7 @@ class PacketList(MutableMapping):
|
|||||||
self._add(packet)
|
self._add(packet)
|
||||||
|
|
||||||
def _add(self, packet):
|
def _add(self, packet):
|
||||||
self[packet.key] = packet
|
self.data["packets"][packet.key] = packet
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return self.d.copy()
|
return self.d.copy()
|
||||||
@ -69,23 +72,23 @@ class PacketList(MutableMapping):
|
|||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
# self.d.move_to_end(key)
|
# self.d.move_to_end(key)
|
||||||
return self.d[key]
|
return self.data["packets"][key]
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
if key in self.d:
|
if key in self.data["packets"]:
|
||||||
self.d.move_to_end(key)
|
self.data["packets"].move_to_end(key)
|
||||||
elif len(self.d) == self.maxlen:
|
elif len(self.data["packets"]) == self.maxlen:
|
||||||
self.d.popitem(last=False)
|
self.data["packets"].popitem(last=False)
|
||||||
self.d[key] = value
|
self.data["packets"][key] = value
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
del self.d[key]
|
del self.data["packets"][key]
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self.d.__iter__()
|
return self.data["packets"].__iter__()
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.d)
|
return len(self.data["packets"])
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def total_rx(self):
|
def total_rx(self):
|
||||||
@ -100,7 +103,8 @@ class PacketList(MutableMapping):
|
|||||||
"total_tracked": self.total_tx() + self.total_rx(),
|
"total_tracked": self.total_tx() + self.total_rx(),
|
||||||
"rx": self.total_rx(),
|
"rx": self.total_rx(),
|
||||||
"tx": self.total_tx(),
|
"tx": self.total_tx(),
|
||||||
"packets": self.types,
|
"types": self.data["types"],
|
||||||
|
"packets": self.data["packets"],
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats
|
return stats
|
||||||
|
@ -28,11 +28,7 @@ class SeenList(objectstore.ObjectStoreMixin):
|
|||||||
|
|
||||||
def stats(self, serializable=False):
|
def stats(self, serializable=False):
|
||||||
"""Return the stats for the PacketTrack class."""
|
"""Return the stats for the PacketTrack class."""
|
||||||
stats = self.data
|
return self.data
|
||||||
# if serializable:
|
|
||||||
# for call in self.data:
|
|
||||||
# stats[call]["last"] = stats[call]["last"].isoformat()
|
|
||||||
return stats
|
|
||||||
|
|
||||||
@wrapt.synchronized(lock)
|
@wrapt.synchronized(lock)
|
||||||
def update_seen(self, packet):
|
def update_seen(self, packet):
|
||||||
|
@ -3,6 +3,8 @@ import decimal
|
|||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from aprsd.packets import core
|
||||||
|
|
||||||
|
|
||||||
class EnhancedJSONEncoder(json.JSONEncoder):
|
class EnhancedJSONEncoder(json.JSONEncoder):
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
@ -54,6 +56,8 @@ class SimpleJSONEncoder(json.JSONEncoder):
|
|||||||
return str(obj)
|
return str(obj)
|
||||||
elif isinstance(obj, decimal.Decimal):
|
elif isinstance(obj, decimal.Decimal):
|
||||||
return str(obj)
|
return str(obj)
|
||||||
|
elif isinstance(obj, core.Packet):
|
||||||
|
return obj.to_dict()
|
||||||
else:
|
else:
|
||||||
return super().default(obj)
|
return super().default(obj)
|
||||||
|
|
||||||
|
@ -327,7 +327,6 @@ function updatePacketTypesChart() {
|
|||||||
option = {
|
option = {
|
||||||
series: series
|
series: series
|
||||||
}
|
}
|
||||||
console.log(option)
|
|
||||||
packet_types_chart.setOption(option);
|
packet_types_chart.setOption(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,22 +380,23 @@ function updateAcksChart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_stats( data ) {
|
function update_stats( data ) {
|
||||||
console.log(data);
|
console.log("update_stats() echarts.js called")
|
||||||
our_callsign = data["APRSDStats"]["callsign"];
|
stats = data["stats"];
|
||||||
$("#version").text( data["APRSDStats"]["version"] );
|
our_callsign = stats["APRSDStats"]["callsign"];
|
||||||
$("#aprs_connection").html( data["aprs_connection"] );
|
$("#version").text( stats["APRSDStats"]["version"] );
|
||||||
$("#uptime").text( "uptime: " + data["APRSDStats"]["uptime"] );
|
$("#aprs_connection").html( stats["aprs_connection"] );
|
||||||
|
$("#uptime").text( "uptime: " + stats["APRSDStats"]["uptime"] );
|
||||||
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
const html_pretty = Prism.highlight(JSON.stringify(data, null, '\t'), Prism.languages.json, 'json');
|
||||||
$("#jsonstats").html(html_pretty);
|
$("#jsonstats").html(html_pretty);
|
||||||
|
|
||||||
t = Date.parse(data["time"]);
|
t = Date.parse(data["time"]);
|
||||||
ts = new Date(t);
|
ts = new Date(t);
|
||||||
updatePacketData(packets_chart, ts, data["PacketList"]["tx"], data["PacketList"]["rx"]);
|
updatePacketData(packets_chart, ts, stats["PacketList"]["tx"], stats["PacketList"]["rx"]);
|
||||||
updatePacketTypesData(ts, data["PacketList"]["packets"]);
|
updatePacketTypesData(ts, stats["PacketList"]["types"]);
|
||||||
updatePacketTypesChart();
|
updatePacketTypesChart();
|
||||||
updateMessagesChart();
|
updateMessagesChart();
|
||||||
updateAcksChart();
|
updateAcksChart();
|
||||||
updateMemChart(ts, data["APRSDStats"]["memory_current"], data["APRSDStats"]["memory_peak"]);
|
updateMemChart(ts, stats["APRSDStats"]["memory_current"], stats["APRSDStats"]["memory_peak"]);
|
||||||
//updateQuadData(message_chart, short_time, data["stats"]["messages"]["sent"], data["stats"]["messages"]["received"], data["stats"]["messages"]["ack_sent"], data["stats"]["messages"]["ack_recieved"]);
|
//updateQuadData(message_chart, short_time, data["stats"]["messages"]["sent"], data["stats"]["messages"]["received"], data["stats"]["messages"]["ack_sent"], data["stats"]["messages"]["ack_recieved"]);
|
||||||
//updateDualData(email_chart, short_time, data["stats"]["email"]["sent"], data["stats"]["email"]["recieved"]);
|
//updateDualData(email_chart, short_time, data["stats"]["email"]["sent"], data["stats"]["email"]["recieved"]);
|
||||||
//updateDualData(memory_chart, short_time, data["stats"]["aprsd"]["memory_peak"], data["stats"]["aprsd"]["memory_current"]);
|
//updateDualData(memory_chart, short_time, data["stats"]["aprsd"]["memory_peak"], data["stats"]["aprsd"]["memory_current"]);
|
||||||
|
@ -25,10 +25,11 @@ function ord(str){return str.charCodeAt(0);}
|
|||||||
|
|
||||||
function update_watchlist( data ) {
|
function update_watchlist( data ) {
|
||||||
// Update the watch list
|
// Update the watch list
|
||||||
|
stats = data["stats"];
|
||||||
var watchdiv = $("#watchDiv");
|
var watchdiv = $("#watchDiv");
|
||||||
var html_str = '<table class="ui celled striped table"><thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th></tr></thead><tbody>'
|
var html_str = '<table class="ui celled striped table"><thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th></tr></thead><tbody>'
|
||||||
watchdiv.html('')
|
watchdiv.html('')
|
||||||
jQuery.each(data["WatchList"], function(i, val) {
|
jQuery.each(stats["WatchList"], function(i, val) {
|
||||||
html_str += '<tr><td class="collapsing"><img id="callsign_'+i+'" class="aprsd_1"></img>' + i + '</td><td>' + val["last"] + '</td></tr>'
|
html_str += '<tr><td class="collapsing"><img id="callsign_'+i+'" class="aprsd_1"></img>' + i + '</td><td>' + val["last"] + '</td></tr>'
|
||||||
});
|
});
|
||||||
html_str += "</tbody></table>";
|
html_str += "</tbody></table>";
|
||||||
@ -60,12 +61,13 @@ function update_watchlist_from_packet(callsign, val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_seenlist( data ) {
|
function update_seenlist( data ) {
|
||||||
|
stats = data["stats"];
|
||||||
var seendiv = $("#seenDiv");
|
var seendiv = $("#seenDiv");
|
||||||
var html_str = '<table class="ui celled striped table">'
|
var html_str = '<table class="ui celled striped table">'
|
||||||
html_str += '<thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th>'
|
html_str += '<thead><tr><th>HAM Callsign</th><th>Age since last seen by APRSD</th>'
|
||||||
html_str += '<th>Number of packets RX</th></tr></thead><tbody>'
|
html_str += '<th>Number of packets RX</th></tr></thead><tbody>'
|
||||||
seendiv.html('')
|
seendiv.html('')
|
||||||
var seen_list = data["SeenList"]
|
var seen_list = stats["SeenList"]
|
||||||
var len = Object.keys(seen_list).length
|
var len = Object.keys(seen_list).length
|
||||||
$('#seen_count').html(len)
|
$('#seen_count').html(len)
|
||||||
jQuery.each(seen_list, function(i, val) {
|
jQuery.each(seen_list, function(i, val) {
|
||||||
@ -79,6 +81,7 @@ function update_seenlist( data ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update_plugins( data ) {
|
function update_plugins( data ) {
|
||||||
|
stats = data["stats"];
|
||||||
var plugindiv = $("#pluginDiv");
|
var plugindiv = $("#pluginDiv");
|
||||||
var html_str = '<table class="ui celled striped table"><thead><tr>'
|
var html_str = '<table class="ui celled striped table"><thead><tr>'
|
||||||
html_str += '<th>Plugin Name</th><th>Plugin Enabled?</th>'
|
html_str += '<th>Plugin Name</th><th>Plugin Enabled?</th>'
|
||||||
@ -87,7 +90,7 @@ function update_plugins( data ) {
|
|||||||
html_str += '</tr></thead><tbody>'
|
html_str += '</tr></thead><tbody>'
|
||||||
plugindiv.html('')
|
plugindiv.html('')
|
||||||
|
|
||||||
var plugins = data["PluginManager"];
|
var plugins = stats["PluginManager"];
|
||||||
var keys = Object.keys(plugins);
|
var keys = Object.keys(plugins);
|
||||||
keys.sort();
|
keys.sort();
|
||||||
for (var i=0; i<keys.length; i++) { // now lets iterate in sort order
|
for (var i=0; i<keys.length; i++) { // now lets iterate in sort order
|
||||||
@ -107,8 +110,8 @@ function update_packets( data ) {
|
|||||||
if (size_dict(packet_list) == 0 && size_dict(data) > 0) {
|
if (size_dict(packet_list) == 0 && size_dict(data) > 0) {
|
||||||
packetsdiv.html('')
|
packetsdiv.html('')
|
||||||
}
|
}
|
||||||
jQuery.each(data, function(i, val) {
|
jQuery.each(data.packets, function(i, val) {
|
||||||
pkt = JSON.parse(val);
|
pkt = val;
|
||||||
|
|
||||||
update_watchlist_from_packet(pkt['from_call'], pkt);
|
update_watchlist_from_packet(pkt['from_call'], pkt);
|
||||||
if ( packet_list.hasOwnProperty(pkt['timestamp']) == false ) {
|
if ( packet_list.hasOwnProperty(pkt['timestamp']) == false ) {
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
var color = Chart.helpers.color;
|
var color = Chart.helpers.color;
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
console.log(initial_stats);
|
|
||||||
start_update();
|
start_update();
|
||||||
start_charts();
|
start_charts();
|
||||||
init_messages();
|
init_messages();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import datetime
|
||||||
import importlib.metadata as imp
|
import importlib.metadata as imp
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
@ -48,10 +49,13 @@ def verify_password(username, password):
|
|||||||
def _stats():
|
def _stats():
|
||||||
stats_obj = stats_threads.StatsStore()
|
stats_obj = stats_threads.StatsStore()
|
||||||
stats_obj.load()
|
stats_obj.load()
|
||||||
# now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
# time_format = "%m-%d-%Y %H:%M:%S"
|
time_format = "%m-%d-%Y %H:%M:%S"
|
||||||
stats_dict = stats_obj.data
|
stats = {
|
||||||
return stats_dict
|
"time": now.strftime(time_format),
|
||||||
|
"stats": stats_obj.data,
|
||||||
|
}
|
||||||
|
return stats
|
||||||
|
|
||||||
|
|
||||||
@app.route("/stats")
|
@app.route("/stats")
|
||||||
@ -71,7 +75,7 @@ def index():
|
|||||||
transport = "aprs-is"
|
transport = "aprs-is"
|
||||||
aprs_connection = (
|
aprs_connection = (
|
||||||
"APRS-IS Server: <a href='http://status.aprs2.net' >"
|
"APRS-IS Server: <a href='http://status.aprs2.net' >"
|
||||||
"{}</a>".format(stats["APRSClientStats"]["server_string"])
|
"{}</a>".format(stats["stats"]["APRSClientStats"]["server_string"])
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# We might be connected to a KISS socket?
|
# We might be connected to a KISS socket?
|
||||||
@ -92,8 +96,8 @@ def index():
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
stats["transport"] = transport
|
stats["stats"]["APRSClientStats"]["transport"] = transport
|
||||||
stats["aprs_connection"] = aprs_connection
|
stats["stats"]["APRSClientStats"]["aprs_connection"] = aprs_connection
|
||||||
entries = conf.conf_to_dict()
|
entries = conf.conf_to_dict()
|
||||||
|
|
||||||
return flask.render_template(
|
return flask.render_template(
|
||||||
@ -113,7 +117,6 @@ def index():
|
|||||||
|
|
||||||
@auth.login_required
|
@auth.login_required
|
||||||
def messages():
|
def messages():
|
||||||
_stats()
|
|
||||||
track = packets.PacketTrack()
|
track = packets.PacketTrack()
|
||||||
msgs = []
|
msgs = []
|
||||||
for id in track:
|
for id in track:
|
||||||
@ -126,9 +129,10 @@ def messages():
|
|||||||
@auth.login_required
|
@auth.login_required
|
||||||
@app.route("/packets")
|
@app.route("/packets")
|
||||||
def get_packets():
|
def get_packets():
|
||||||
LOG.debug("/packets called")
|
stats = _stats()
|
||||||
stats_dict = _stats()
|
stats_dict = stats["stats"]
|
||||||
return json.dumps(stats_dict.get("PacketList", {}))
|
packets = stats_dict.get("PacketList", {})
|
||||||
|
return json.dumps(packets, cls=aprsd_json.SimpleJSONEncoder)
|
||||||
|
|
||||||
|
|
||||||
@auth.login_required
|
@auth.login_required
|
||||||
|
Loading…
Reference in New Issue
Block a user