diff --git a/aprsd/client.py b/aprsd/client.py
index 9c9522d..08df034 100644
--- a/aprsd/client.py
+++ b/aprsd/client.py
@@ -152,9 +152,10 @@ class APRSISClient(Client):
except LoginError as e:
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
connected = False
- raise e
+ time.sleep(backoff)
except Exception as e:
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
+ connected = False
time.sleep(backoff)
backoff = backoff * 2
continue
diff --git a/aprsd/clients/aprsis.py b/aprsd/clients/aprsis.py
index 5ba53b1..aa1a9ba 100644
--- a/aprsd/clients/aprsis.py
+++ b/aprsd/clients/aprsis.py
@@ -112,23 +112,23 @@ class Aprsdis(aprslib.IS):
self._sendall(login_str)
self.sock.settimeout(5)
test = self.sock.recv(len(login_str) + 100)
+ self.logger.debug("Server: '%s'", test)
if is_py3:
test = test.decode("latin-1")
test = test.rstrip()
- self.logger.debug("Server: %s", test)
+ self.logger.debug("Server: '%s'", test)
- a, b, callsign, status, e = test.split(" ", 4)
+ if not test:
+ raise LoginError(f"Server Response Empty: '{test}'")
+
+ _, _, callsign, status, e = test.split(" ", 4)
s = e.split(",")
if len(s):
server_string = s[0].replace("server ", "")
else:
server_string = e.replace("server ", "")
- self.logger.info(f"Connected to {server_string}")
- self.server_string = server_string
- stats.APRSDStats().set_aprsis_server(server_string)
-
if callsign == "":
raise LoginError("Server responded with empty callsign???")
if callsign != self.callsign:
@@ -141,6 +141,10 @@ class Aprsdis(aprslib.IS):
else:
self.logger.info("Login successful")
+ self.logger.info(f"Connected to {server_string}")
+ self.server_string = server_string
+ stats.APRSDStats().set_aprsis_server(server_string)
+
except LoginError as e:
self.logger.error(str(e))
self.close()
@@ -148,6 +152,7 @@ class Aprsdis(aprslib.IS):
except Exception as e:
self.close()
self.logger.error(f"Failed to login '{e}'")
+ self.logger.exception(e)
raise LoginError("Failed to login")
def consumer(self, callback, blocking=True, immortal=False, raw=False):
diff --git a/aprsd/cmds/webchat.py b/aprsd/cmds/webchat.py
index c0e719d..fbdc87d 100644
--- a/aprsd/cmds/webchat.py
+++ b/aprsd/cmds/webchat.py
@@ -12,7 +12,6 @@ import click
import flask
from flask import request
from flask.logging import default_handler
-import flask_classful
from flask_httpauth import HTTPBasicAuth
from flask_socketio import Namespace, SocketIO
from oslo_config import cfg
@@ -31,9 +30,16 @@ from aprsd.utils import objectstore, trace
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
auth = HTTPBasicAuth()
-users = None
+users = {}
socketio = None
+flask_app = flask.Flask(
+ "aprsd",
+ static_url_path="/static",
+ static_folder="web/chat/static",
+ template_folder="web/chat/templates",
+)
+
def signal_handler(sig, frame):
@@ -174,106 +180,108 @@ class WebChatProcessPacketThread(rx.APRSDProcessPacketThread):
)
-class WebChatFlask(flask_classful.FlaskView):
+def set_config():
+ global users
- def set_config(self):
- global users
- self.users = {}
- user = CONF.admin.user
- self.users[user] = generate_password_hash(CONF.admin.password)
- users = self.users
- def _get_transport(self, stats):
- if CONF.aprs_network.enabled:
- transport = "aprs-is"
- aprs_connection = (
- "APRS-IS Server: "
- "{}".format(stats["stats"]["aprs-is"]["server"])
- )
- else:
- # We might be connected to a KISS socket?
- if client.KISSClient.is_enabled():
- transport = client.KISSClient.transport()
- if transport == client.TRANSPORT_TCPKISS:
- aprs_connection = (
- "TCPKISS://{}:{}".format(
- CONF.kiss_tcp.host,
- CONF.kiss_tcp.port,
- )
- )
- elif transport == client.TRANSPORT_SERIALKISS:
- # for pep8 violation
- aprs_connection = (
- "SerialKISS://{}@{} baud".format(
- CONF.kiss_serial.device,
- CONF.kiss_serial.baudrate,
- ),
- )
-
- return transport, aprs_connection
-
- @auth.login_required
- def index(self):
- ua_str = request.headers.get("User-Agent")
- # this takes about 2 seconds :(
- user_agent = ua_parse(ua_str)
- LOG.debug(f"Is mobile? {user_agent.is_mobile}")
- stats = self._stats()
-
- if user_agent.is_mobile:
- html_template = "mobile.html"
- else:
- html_template = "index.html"
-
- # For development
- # html_template = "mobile.html"
-
- LOG.debug(f"Template {html_template}")
-
- transport, aprs_connection = self._get_transport(stats)
- LOG.debug(f"transport {transport} aprs_connection {aprs_connection}")
-
- stats["transport"] = transport
- stats["aprs_connection"] = aprs_connection
- LOG.debug(f"initial stats = {stats}")
-
- return flask.render_template(
- html_template,
- initial_stats=stats,
- aprs_connection=aprs_connection,
- callsign=CONF.callsign,
- version=aprsd.__version__,
+def _get_transport(stats):
+ if CONF.aprs_network.enabled:
+ transport = "aprs-is"
+ aprs_connection = (
+ "APRS-IS Server: "
+ "{}".format(stats["stats"]["aprs-is"]["server"])
)
+ else:
+ # We might be connected to a KISS socket?
+ if client.KISSClient.is_enabled():
+ transport = client.KISSClient.transport()
+ if transport == client.TRANSPORT_TCPKISS:
+ aprs_connection = (
+ "TCPKISS://{}:{}".format(
+ CONF.kiss_tcp.host,
+ CONF.kiss_tcp.port,
+ )
+ )
+ elif transport == client.TRANSPORT_SERIALKISS:
+ # for pep8 violation
+ aprs_connection = (
+ "SerialKISS://{}@{} baud".format(
+ CONF.kiss_serial.device,
+ CONF.kiss_serial.baudrate,
+ ),
+ )
- @auth.login_required
- def send_message_status(self):
- LOG.debug(request)
- msgs = SentMessages()
- info = msgs.get_all()
- return json.dumps(info)
+ return transport, aprs_connection
- def _stats(self):
- stats_obj = stats.APRSDStats()
- now = datetime.datetime.now()
- time_format = "%m-%d-%Y %H:%M:%S"
- stats_dict = stats_obj.stats()
- # Webchat doesnt need these
- del stats_dict["aprsd"]["watch_list"]
- del stats_dict["aprsd"]["seen_list"]
- # del stats_dict["email"]
- # del stats_dict["plugins"]
- # del stats_dict["messages"]
+@auth.login_required
+@flask_app.route("/")
+def index():
+ ua_str = request.headers.get("User-Agent")
+ # this takes about 2 seconds :(
+ user_agent = ua_parse(ua_str)
+ LOG.debug(f"Is mobile? {user_agent.is_mobile}")
+ stats = _stats()
- result = {
- "time": now.strftime(time_format),
- "stats": stats_dict,
- }
+ if user_agent.is_mobile:
+ html_template = "mobile.html"
+ else:
+ html_template = "index.html"
- return result
+ # For development
+ # html_template = "mobile.html"
- def stats(self):
- return json.dumps(self._stats())
+ LOG.debug(f"Template {html_template}")
+
+ transport, aprs_connection = _get_transport(stats)
+ LOG.debug(f"transport {transport} aprs_connection {aprs_connection}")
+
+ stats["transport"] = transport
+ stats["aprs_connection"] = aprs_connection
+ LOG.debug(f"initial stats = {stats}")
+
+ return flask.render_template(
+ html_template,
+ initial_stats=stats,
+ aprs_connection=aprs_connection,
+ callsign=CONF.callsign,
+ version=aprsd.__version__,
+ )
+
+
+@auth.login_required
+@flask_app.route("//send-message-status")
+def send_message_status():
+ LOG.debug(request)
+ msgs = SentMessages()
+ info = msgs.get_all()
+ return json.dumps(info)
+
+
+def _stats():
+ stats_obj = stats.APRSDStats()
+ now = datetime.datetime.now()
+
+ time_format = "%m-%d-%Y %H:%M:%S"
+ stats_dict = stats_obj.stats()
+ # Webchat doesnt need these
+ del stats_dict["aprsd"]["watch_list"]
+ del stats_dict["aprsd"]["seen_list"]
+ # del stats_dict["email"]
+ # del stats_dict["plugins"]
+ # del stats_dict["messages"]
+
+ result = {
+ "time": now.strftime(time_format),
+ "stats": stats_dict,
+ }
+
+ return result
+
+
+@flask_app.route("/stats")
+def get_stats():
+ return json.dumps(_stats())
class SendMessageNamespace(Namespace):
@@ -377,21 +385,9 @@ def setup_logging(flask_app, loglevel, quiet):
@trace.trace
def init_flask(loglevel, quiet):
- global socketio
+ global socketio, flask_app
- flask_app = flask.Flask(
- "aprsd",
- static_url_path="/static",
- static_folder="web/chat/static",
- template_folder="web/chat/templates",
- )
setup_logging(flask_app, loglevel, quiet)
- server = WebChatFlask()
- server.set_config()
- flask_app.route("/", methods=["GET"])(server.index)
- flask_app.route("/stats", methods=["GET"])(server.stats)
- # flask_app.route("/send-message", methods=["GET"])(server.send_message)
- flask_app.route("/send-message-status", methods=["GET"])(server.send_message_status)
socketio = SocketIO(
flask_app, logger=False, engineio_logger=False,
@@ -407,7 +403,7 @@ def init_flask(loglevel, quiet):
"/sendmsg",
),
)
- return socketio, flask_app
+ return socketio
# main() ###
@@ -448,6 +444,8 @@ def webchat(ctx, flush, port):
LOG.info(f"APRSD Started version: {aprsd.__version__}")
CONF.log_opt_values(LOG, logging.DEBUG)
+ user = CONF.admin.user
+ users[user] = generate_password_hash(CONF.admin.password)
# Initialize the client factory and create
# The correct client object ready for use
@@ -466,7 +464,7 @@ def webchat(ctx, flush, port):
packets.WatchList()
packets.SeenList()
- (socketio, app) = init_flask(loglevel, quiet)
+ socketio = init_flask(loglevel, quiet)
rx_thread = rx.APRSDPluginRXThread(
packet_queue=threads.packet_queue,
)
@@ -482,7 +480,7 @@ def webchat(ctx, flush, port):
keepalive.start()
LOG.info("Start socketio.run()")
socketio.run(
- app,
+ flask_app,
ssl_context="adhoc",
host=CONF.admin.web_ip,
port=port,
diff --git a/aprsd/wsgi.py b/aprsd/wsgi.py
index c68511b..17ffbe3 100644
--- a/aprsd/wsgi.py
+++ b/aprsd/wsgi.py
@@ -187,6 +187,7 @@ def index():
plugin_count=plugin_count,
)
+
@auth.login_required
def messages():
track = packets.PacketTrack()
@@ -197,9 +198,10 @@ def messages():
return flask.render_template("messages.html", messages=json.dumps(msgs))
+
@auth.login_required
@app.route("/packets")
-def packets():
+def get_packets():
LOG.debug("/packets called")
packet_list = aprsd_rpc_client.RPCClient().get_packet_list()
if packet_list:
@@ -212,6 +214,7 @@ def packets():
else:
return json.dumps([])
+
@auth.login_required
@app.route("/plugins")
def plugins():
@@ -221,6 +224,7 @@ def plugins():
return "reloaded"
+
@auth.login_required
@app.route("/save")
def save():
@@ -230,7 +234,6 @@ def save():
return json.dumps({"messages": "saved"})
-
class LogUpdateThread(threads.APRSDThread):
def __init__(self):
diff --git a/tests/cmds/test_webchat.py b/tests/cmds/test_webchat.py
index 3a0103d..53deb0d 100644
--- a/tests/cmds/test_webchat.py
+++ b/tests/cmds/test_webchat.py
@@ -39,9 +39,9 @@ class TestSendMessageCommand(unittest.TestCase):
CliRunner()
self.config_and_init()
- socketio, flask_app = webchat.init_flask("DEBUG", False)
+ socketio = webchat.init_flask("DEBUG", False)
self.assertIsInstance(socketio, flask_socketio.SocketIO)
- self.assertIsInstance(flask_app, flask.Flask)
+ self.assertIsInstance(webchat.flask_app, flask.Flask)
@mock.patch("aprsd.packets.tracker.PacketTrack.remove")
@mock.patch("aprsd.cmds.webchat.socketio")