mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-25 17:38:44 -05:00
Refactor utils usage
This patch separates out the config from the utils.py utils.py has grown into a catchall for everything and this patch is the start of that cleanup.
This commit is contained in:
parent
65ea33290a
commit
23e3876e7b
@ -38,11 +38,6 @@ class Client:
|
||||
if config:
|
||||
self.config = config
|
||||
|
||||
def new(self):
|
||||
obj = super().__new__(Client)
|
||||
obj.config = self.config
|
||||
return obj
|
||||
|
||||
@property
|
||||
def client(self):
|
||||
if not self.aprs_client:
|
||||
|
367
aprsd/config.py
Normal file
367
aprsd/config.py
Normal file
@ -0,0 +1,367 @@
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
import click
|
||||
import yaml
|
||||
|
||||
from aprsd import utils
|
||||
|
||||
|
||||
LOG_LEVELS = {
|
||||
"CRITICAL": logging.CRITICAL,
|
||||
"ERROR": logging.ERROR,
|
||||
"WARNING": logging.WARNING,
|
||||
"INFO": logging.INFO,
|
||||
"DEBUG": logging.DEBUG,
|
||||
}
|
||||
|
||||
DEFAULT_DATE_FORMAT = "%m/%d/%Y %I:%M:%S %p"
|
||||
DEFAULT_LOG_FORMAT = (
|
||||
"[%(asctime)s] [%(threadName)-20.20s] [%(levelname)-5.5s]"
|
||||
" %(message)s - [%(pathname)s:%(lineno)d]"
|
||||
)
|
||||
|
||||
QUEUE_DATE_FORMAT = "[%m/%d/%Y] [%I:%M:%S %p]"
|
||||
QUEUE_LOG_FORMAT = (
|
||||
"%(asctime)s [%(threadName)-20.20s] [%(levelname)-5.5s]"
|
||||
" %(message)s - [%(pathname)s:%(lineno)d]"
|
||||
)
|
||||
|
||||
CORE_MESSAGE_PLUGINS = [
|
||||
"aprsd.plugins.email.EmailPlugin",
|
||||
"aprsd.plugins.fortune.FortunePlugin",
|
||||
"aprsd.plugins.location.LocationPlugin",
|
||||
"aprsd.plugins.ping.PingPlugin",
|
||||
"aprsd.plugins.query.QueryPlugin",
|
||||
"aprsd.plugins.stock.StockPlugin",
|
||||
"aprsd.plugins.time.TimePlugin",
|
||||
"aprsd.plugins.weather.USWeatherPlugin",
|
||||
"aprsd.plugins.version.VersionPlugin",
|
||||
]
|
||||
|
||||
CORE_NOTIFY_PLUGINS = [
|
||||
"aprsd.plugins.notify.NotifySeenPlugin",
|
||||
]
|
||||
|
||||
# an example of what should be in the ~/.aprsd/config.yml
|
||||
DEFAULT_CONFIG_DICT = {
|
||||
"ham": {"callsign": "NOCALL"},
|
||||
"aprs": {
|
||||
"enabled": True,
|
||||
"login": "CALLSIGN",
|
||||
"password": "00000",
|
||||
"host": "rotate.aprs2.net",
|
||||
"port": 14580,
|
||||
},
|
||||
"kiss": {
|
||||
"tcp": {
|
||||
"enabled": False,
|
||||
"host": "direwolf.ip.address",
|
||||
"port": "8001",
|
||||
},
|
||||
"serial": {
|
||||
"enabled": False,
|
||||
"device": "/dev/ttyS0",
|
||||
"baudrate": 9600,
|
||||
},
|
||||
},
|
||||
"aprsd": {
|
||||
"logfile": "/tmp/aprsd.log",
|
||||
"logformat": DEFAULT_LOG_FORMAT,
|
||||
"dateformat": DEFAULT_DATE_FORMAT,
|
||||
"trace": False,
|
||||
"enabled_plugins": CORE_MESSAGE_PLUGINS,
|
||||
"units": "imperial",
|
||||
"watch_list": {
|
||||
"enabled": False,
|
||||
# Who gets the alert?
|
||||
"alert_callsign": "NOCALL",
|
||||
# 43200 is 12 hours
|
||||
"alert_time_seconds": 43200,
|
||||
# How many packets to save in a ring Buffer
|
||||
# for a particular callsign
|
||||
"packet_keep_count": 10,
|
||||
"callsigns": [],
|
||||
"enabled_plugins": CORE_NOTIFY_PLUGINS,
|
||||
},
|
||||
"web": {
|
||||
"enabled": True,
|
||||
"logging_enabled": True,
|
||||
"host": "0.0.0.0",
|
||||
"port": 8001,
|
||||
"users": {
|
||||
"admin": "password-here",
|
||||
},
|
||||
},
|
||||
"email": {
|
||||
"enabled": True,
|
||||
"shortcuts": {
|
||||
"aa": "5551239999@vtext.com",
|
||||
"cl": "craiglamparter@somedomain.org",
|
||||
"wb": "555309@vtext.com",
|
||||
},
|
||||
"smtp": {
|
||||
"login": "SMTP_USERNAME",
|
||||
"password": "SMTP_PASSWORD",
|
||||
"host": "smtp.gmail.com",
|
||||
"port": 465,
|
||||
"use_ssl": False,
|
||||
"debug": False,
|
||||
},
|
||||
"imap": {
|
||||
"login": "IMAP_USERNAME",
|
||||
"password": "IMAP_PASSWORD",
|
||||
"host": "imap.gmail.com",
|
||||
"port": 993,
|
||||
"use_ssl": True,
|
||||
"debug": False,
|
||||
},
|
||||
},
|
||||
},
|
||||
"services": {
|
||||
"aprs.fi": {"apiKey": "APIKEYVALUE"},
|
||||
"openweathermap": {"apiKey": "APIKEYVALUE"},
|
||||
"opencagedata": {"apiKey": "APIKEYVALUE"},
|
||||
"avwx": {"base_url": "http://host:port", "apiKey": "APIKEYVALUE"},
|
||||
},
|
||||
}
|
||||
|
||||
home = str(Path.home())
|
||||
DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/"
|
||||
DEFAULT_SAVE_FILE = f"{home}/.config/aprsd/aprsd.p"
|
||||
DEFAULT_CONFIG_FILE = f"{home}/.config/aprsd/aprsd.yml"
|
||||
|
||||
|
||||
def add_config_comments(raw_yaml):
|
||||
end_idx = utils.end_substr(raw_yaml, "aprs:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = utils.insert_str(
|
||||
raw_yaml,
|
||||
"\n # Set enabled to False if there is no internet connectivity."
|
||||
"\n # This is useful for a direwolf KISS aprs connection only. "
|
||||
"\n"
|
||||
"\n # Get the passcode for your callsign here: "
|
||||
"\n # https://apps.magicbug.co.uk/passcode",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = utils.end_substr(raw_yaml, "aprs.fi:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = utils.insert_str(
|
||||
raw_yaml,
|
||||
"\n # Get the apiKey from your aprs.fi account here: "
|
||||
"\n # http://aprs.fi/account",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = utils.end_substr(raw_yaml, "opencagedata:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = utils.insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for TimeOpenCageDataPlugin) "
|
||||
"\n # Get the apiKey from your opencagedata account here: "
|
||||
"\n # https://opencagedata.com/dashboard#api-keys",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = utils.end_substr(raw_yaml, "openweathermap:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = utils.insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for OWMWeatherPlugin) "
|
||||
"\n # Get the apiKey from your "
|
||||
"\n # openweathermap account here: "
|
||||
"\n # https://home.openweathermap.org/api_keys",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = utils.end_substr(raw_yaml, "avwx:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = utils.insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for AVWXWeatherPlugin) "
|
||||
"\n # Use hosted avwx-api here: https://avwx.rest "
|
||||
"\n # or deploy your own from here: "
|
||||
"\n # https://github.com/avwx-rest/avwx-api",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
return raw_yaml
|
||||
|
||||
|
||||
def dump_default_cfg():
|
||||
return add_config_comments(
|
||||
yaml.dump(
|
||||
DEFAULT_CONFIG_DICT,
|
||||
indent=4,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def create_default_config():
|
||||
"""Create a default config file."""
|
||||
# make sure the directory location exists
|
||||
config_file_expanded = os.path.expanduser(DEFAULT_CONFIG_FILE)
|
||||
config_dir = os.path.dirname(config_file_expanded)
|
||||
if not os.path.exists(config_dir):
|
||||
click.echo(f"Config dir '{config_dir}' doesn't exist, creating.")
|
||||
utils.mkdir_p(config_dir)
|
||||
with open(config_file_expanded, "w+") as cf:
|
||||
cf.write(dump_default_cfg())
|
||||
|
||||
|
||||
def get_config(config_file):
|
||||
"""This tries to read the yaml config from <config_file>."""
|
||||
config_file_expanded = os.path.expanduser(config_file)
|
||||
if os.path.exists(config_file_expanded):
|
||||
with open(config_file_expanded) as stream:
|
||||
config = yaml.load(stream, Loader=yaml.FullLoader)
|
||||
return config
|
||||
else:
|
||||
if config_file == DEFAULT_CONFIG_FILE:
|
||||
click.echo(
|
||||
f"{config_file_expanded} is missing, creating config file",
|
||||
)
|
||||
create_default_config()
|
||||
msg = (
|
||||
"Default config file created at {}. Please edit with your "
|
||||
"settings.".format(config_file)
|
||||
)
|
||||
click.echo(msg)
|
||||
else:
|
||||
# The user provided a config file path different from the
|
||||
# Default, so we won't try and create it, just bitch and bail.
|
||||
msg = f"Custom config file '{config_file}' is missing."
|
||||
click.echo(msg)
|
||||
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
# This method tries to parse the config yaml file
|
||||
# and consume the settings.
|
||||
# If the required params don't exist,
|
||||
# it will look in the environment
|
||||
def parse_config(config_file):
|
||||
# for now we still use globals....ugh
|
||||
global CONFIG
|
||||
|
||||
def fail(msg):
|
||||
click.echo(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
def check_option(config, chain, default_fail=None):
|
||||
try:
|
||||
config = check_config_option(config, chain, default_fail=default_fail)
|
||||
except Exception as ex:
|
||||
fail(repr(ex))
|
||||
else:
|
||||
return config
|
||||
|
||||
config = get_config(config_file)
|
||||
|
||||
# special check here to make sure user has edited the config file
|
||||
# and changed the ham callsign
|
||||
check_option(
|
||||
config,
|
||||
[
|
||||
"ham",
|
||||
"callsign",
|
||||
],
|
||||
default_fail=DEFAULT_CONFIG_DICT["ham"]["callsign"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["services", "aprs.fi", "apiKey"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["services"]["aprs.fi"]["apiKey"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprs", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprs"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprs", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprs"]["password"],
|
||||
)
|
||||
|
||||
# Ensure they change the admin password
|
||||
if config["aprsd"]["web"]["enabled"] is True:
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "web", "users", "admin"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["web"]["users"]["admin"],
|
||||
)
|
||||
|
||||
if config["aprsd"]["watch_list"]["enabled"] is True:
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "watch_list", "alert_callsign"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["watch_list"]["alert_callsign"],
|
||||
)
|
||||
|
||||
if config["aprsd"]["email"]["enabled"] is True:
|
||||
# Check IMAP server settings
|
||||
check_option(config, ["aprsd", "email", "imap", "host"])
|
||||
check_option(config, ["aprsd", "email", "imap", "port"])
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "imap", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["imap"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "imap", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["imap"]["password"],
|
||||
)
|
||||
|
||||
# Check SMTP server settings
|
||||
check_option(config, ["aprsd", "email", "smtp", "host"])
|
||||
check_option(config, ["aprsd", "email", "smtp", "port"])
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "smtp", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["smtp"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "smtp", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["smtp"]["password"],
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def conf_option_exists(conf, chain):
|
||||
_key = chain.pop(0)
|
||||
if _key in conf:
|
||||
return conf_option_exists(conf[_key], chain) if chain else conf[_key]
|
||||
|
||||
|
||||
def check_config_option(config, chain, default_fail=None):
|
||||
result = conf_option_exists(config, chain.copy())
|
||||
if result is None:
|
||||
raise Exception(
|
||||
"'{}' was not in config file".format(
|
||||
chain,
|
||||
),
|
||||
)
|
||||
else:
|
||||
if default_fail:
|
||||
if result == default_fail:
|
||||
# We have to fail and bail if the user hasn't edited
|
||||
# this config option.
|
||||
raise Exception(
|
||||
"Config file needs to be edited from provided defaults for {}.".format(
|
||||
chain,
|
||||
),
|
||||
)
|
||||
else:
|
||||
return config
|
@ -14,7 +14,9 @@ import click_completion
|
||||
|
||||
# local imports here
|
||||
import aprsd
|
||||
from aprsd import client, plugin, utils
|
||||
from aprsd import client
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import plugin
|
||||
|
||||
|
||||
# setup the global logger
|
||||
@ -156,7 +158,7 @@ def setup_logging(config, loglevel, quiet):
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
@ -178,7 +180,7 @@ def test_plugin(
|
||||
):
|
||||
"""APRSD Plugin test app."""
|
||||
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
|
||||
setup_logging(config, loglevel, False)
|
||||
LOG.info(f"Test APRSD PLugin version: {aprsd.__version__}")
|
||||
|
@ -17,9 +17,9 @@ from flask_socketio import Namespace, SocketIO
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
|
||||
import aprsd
|
||||
from aprsd import (
|
||||
client, kissclient, messaging, packets, plugin, stats, threads, utils,
|
||||
)
|
||||
from aprsd import client
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import kissclient, messaging, packets, plugin, stats, threads, utils
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
@ -553,10 +553,10 @@ def setup_logging(config, flask_app, loglevel, quiet):
|
||||
flask_app.logger.disabled = True
|
||||
return
|
||||
|
||||
log_level = utils.LOG_LEVELS[loglevel]
|
||||
log_level = aprsd_config.LOG_LEVELS[loglevel]
|
||||
LOG.setLevel(log_level)
|
||||
log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT)
|
||||
log_format = config["aprsd"].get("logformat", aprsd_config.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", aprsd_config.DEFAULT_DATE_FORMAT)
|
||||
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
||||
log_file = config["aprsd"].get("logfile", None)
|
||||
if log_file:
|
||||
|
@ -19,7 +19,7 @@ import requests
|
||||
|
||||
# local imports here
|
||||
import aprsd
|
||||
from aprsd import utils
|
||||
from aprsd import config as aprsd_config
|
||||
|
||||
|
||||
# setup the global logger
|
||||
@ -172,7 +172,7 @@ def parse_delta_str(s):
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
@ -191,7 +191,7 @@ def parse_delta_str(s):
|
||||
def check(loglevel, config_file, health_url, timeout):
|
||||
"""APRSD Plugin test app."""
|
||||
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
|
||||
setup_logging(config, loglevel, False)
|
||||
LOG.debug(f"APRSD HealthCheck version: {aprsd.__version__}")
|
||||
|
@ -36,7 +36,9 @@ import click_completion
|
||||
|
||||
# local imports here
|
||||
import aprsd
|
||||
from aprsd import client, messaging, stats, threads, trace, utils
|
||||
from aprsd import client
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import messaging, stats, threads, trace, utils
|
||||
|
||||
|
||||
# setup the global logger
|
||||
@ -169,10 +171,10 @@ def signal_handler(sig, frame):
|
||||
# to disable logging to stdout, but still log to file
|
||||
# use the --quiet option on the cmdln
|
||||
def setup_logging(config, loglevel, quiet):
|
||||
log_level = utils.LOG_LEVELS[loglevel]
|
||||
log_level = aprsd_config.LOG_LEVELS[loglevel]
|
||||
LOG.setLevel(log_level)
|
||||
log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT)
|
||||
log_format = config["aprsd"].get("logformat", aprsd_config.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", aprsd_config.DEFAULT_DATE_FORMAT)
|
||||
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
||||
log_file = config["aprsd"].get("logfile", None)
|
||||
if log_file:
|
||||
@ -218,7 +220,7 @@ def setup_logging(config, loglevel, quiet):
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
@ -258,7 +260,7 @@ def listen(
|
||||
"""Send a message to a callsign via APRS_IS."""
|
||||
global got_ack, got_response
|
||||
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
if not aprs_login:
|
||||
click.echo("Must set --aprs_login or APRS_LOGIN")
|
||||
return
|
||||
|
@ -37,9 +37,10 @@ import click_completion
|
||||
# local imports here
|
||||
import aprsd
|
||||
from aprsd import (
|
||||
client, flask, kissclient, messaging, packets, plugin, stats, threads,
|
||||
trace, utils,
|
||||
flask, kissclient, messaging, packets, plugin, stats, threads, trace, utils,
|
||||
)
|
||||
from aprsd import client
|
||||
from aprsd import config as aprsd_config
|
||||
|
||||
|
||||
# setup the global logger
|
||||
@ -48,22 +49,8 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
|
||||
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
|
||||
flask_enabled = False
|
||||
|
||||
# server_event = threading.Event()
|
||||
|
||||
# localization, please edit:
|
||||
# HOST = "noam.aprs2.net" # north america tier2 servers round robin
|
||||
# USER = "KM6XXX-9" # callsign of this aprs client with SSID
|
||||
# PASS = "99999" # google how to generate this
|
||||
# BASECALLSIGN = "KM6XXX" # callsign of radio in the field to send email
|
||||
# shortcuts = {
|
||||
# "aa" : "5551239999@vtext.com",
|
||||
# "cl" : "craiglamparter@somedomain.org",
|
||||
# "wb" : "5553909472@vtext.com"
|
||||
# }
|
||||
|
||||
|
||||
def custom_startswith(string, incomplete):
|
||||
"""A custom completion match that supports case insensitive matching."""
|
||||
@ -172,10 +159,10 @@ def signal_handler(sig, frame):
|
||||
# to disable logging to stdout, but still log to file
|
||||
# use the --quiet option on the cmdln
|
||||
def setup_logging(config, loglevel, quiet):
|
||||
log_level = utils.LOG_LEVELS[loglevel]
|
||||
log_level = aprsd_config.LOG_LEVELS[loglevel]
|
||||
LOG.setLevel(log_level)
|
||||
log_format = config["aprsd"].get("logformat", utils.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", utils.DEFAULT_DATE_FORMAT)
|
||||
log_format = config["aprsd"].get("logformat", aprsd_config.DEFAULT_LOG_FORMAT)
|
||||
date_format = config["aprsd"].get("dateformat", aprsd_config.DEFAULT_DATE_FORMAT)
|
||||
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
||||
log_file = config["aprsd"].get("logfile", None)
|
||||
if log_file:
|
||||
@ -196,15 +183,15 @@ def setup_logging(config, loglevel, quiet):
|
||||
imap_logger.addHandler(fh)
|
||||
|
||||
if (
|
||||
utils.check_config_option(
|
||||
aprsd_config.check_config_option(
|
||||
config, ["aprsd", "web", "enabled"],
|
||||
default_fail=False,
|
||||
)
|
||||
):
|
||||
qh = logging.handlers.QueueHandler(threads.logging_queue)
|
||||
q_log_formatter = logging.Formatter(
|
||||
fmt=utils.QUEUE_LOG_FORMAT,
|
||||
datefmt=utils.QUEUE_DATE_FORMAT,
|
||||
fmt=aprsd_config.QUEUE_LOG_FORMAT,
|
||||
datefmt=aprsd_config.QUEUE_DATE_FORMAT,
|
||||
)
|
||||
qh.setFormatter(q_log_formatter)
|
||||
LOG.addHandler(qh)
|
||||
@ -234,11 +221,11 @@ def setup_logging(config, loglevel, quiet):
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
def check_version(loglevel, config_file):
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
|
||||
setup_logging(config, loglevel, False)
|
||||
level, msg = utils._check_version()
|
||||
@ -251,7 +238,7 @@ def check_version(loglevel, config_file):
|
||||
@main.command()
|
||||
def sample_config():
|
||||
"""This dumps the config to stdout."""
|
||||
click.echo(utils.dump_default_cfg())
|
||||
click.echo(aprsd_config.dump_default_cfg())
|
||||
|
||||
|
||||
@main.command()
|
||||
@ -272,7 +259,7 @@ def sample_config():
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
@ -312,7 +299,7 @@ def send_message(
|
||||
"""Send a message to a callsign via APRS_IS."""
|
||||
global got_ack, got_response
|
||||
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
if not aprs_login:
|
||||
click.echo("Must set --aprs_login or APRS_LOGIN")
|
||||
return
|
||||
@ -429,7 +416,7 @@ def send_message(
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=utils.DEFAULT_CONFIG_FILE,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
@ -454,7 +441,7 @@ def server(
|
||||
if not quiet:
|
||||
click.echo("Load config")
|
||||
|
||||
config = utils.parse_config(config_file)
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
|
||||
setup_logging(config, loglevel, quiet)
|
||||
level, msg = utils._check_version()
|
||||
@ -523,7 +510,7 @@ def server(
|
||||
keepalive = threads.KeepAliveThread(config=config)
|
||||
keepalive.start()
|
||||
|
||||
web_enabled = utils.check_config_option(config, ["aprsd", "web", "enabled"], default_fail=False)
|
||||
web_enabled = aprsd_config.check_config_option(config, ["aprsd", "web", "enabled"], default_fail=False)
|
||||
|
||||
if web_enabled:
|
||||
flask_enabled = True
|
||||
|
@ -9,7 +9,9 @@ import re
|
||||
import threading
|
||||
import time
|
||||
|
||||
from aprsd import client, kissclient, packets, stats, threads, trace, utils
|
||||
from aprsd import client
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import kissclient, packets, stats, threads, trace
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
@ -113,11 +115,11 @@ class MsgTrack:
|
||||
LOG.debug(f"Save tracker to disk? {len(self)}")
|
||||
if len(self) > 0:
|
||||
LOG.info(f"Saving {len(self)} tracking messages to disk")
|
||||
pickle.dump(self.dump(), open(utils.DEFAULT_SAVE_FILE, "wb+"))
|
||||
pickle.dump(self.dump(), open(aprsd_config.DEFAULT_SAVE_FILE, "wb+"))
|
||||
else:
|
||||
LOG.debug(
|
||||
"Nothing to save, flushing old save file '{}'".format(
|
||||
utils.DEFAULT_SAVE_FILE,
|
||||
aprsd_config.DEFAULT_SAVE_FILE,
|
||||
),
|
||||
)
|
||||
self.flush()
|
||||
@ -131,8 +133,8 @@ class MsgTrack:
|
||||
return dump
|
||||
|
||||
def load(self):
|
||||
if os.path.exists(utils.DEFAULT_SAVE_FILE):
|
||||
raw = pickle.load(open(utils.DEFAULT_SAVE_FILE, "rb"))
|
||||
if os.path.exists(aprsd_config.DEFAULT_SAVE_FILE):
|
||||
raw = pickle.load(open(aprsd_config.DEFAULT_SAVE_FILE, "rb"))
|
||||
if raw:
|
||||
self.track = raw
|
||||
LOG.debug("Loaded MsgTrack dict from disk.")
|
||||
@ -171,8 +173,8 @@ class MsgTrack:
|
||||
|
||||
def flush(self):
|
||||
"""Nuke the old pickle file that stored the old results from last aprsd run."""
|
||||
if os.path.exists(utils.DEFAULT_SAVE_FILE):
|
||||
pathlib.Path(utils.DEFAULT_SAVE_FILE).unlink()
|
||||
if os.path.exists(aprsd_config.DEFAULT_SAVE_FILE):
|
||||
pathlib.Path(aprsd_config.DEFAULT_SAVE_FILE).unlink()
|
||||
with self.lock:
|
||||
self.track = {}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import logging
|
||||
import re
|
||||
import time
|
||||
|
||||
from aprsd import plugin, plugin_utils, trace, utils
|
||||
from aprsd import config, plugin, plugin_utils, trace
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
@ -24,7 +24,7 @@ class LocationPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
|
||||
# get last location of a callsign, get descriptive name from weather service
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
|
@ -5,7 +5,7 @@ import time
|
||||
from opencage.geocoder import OpenCageGeocode
|
||||
import pytz
|
||||
|
||||
from aprsd import fuzzyclock, plugin, plugin_utils, trace, utils
|
||||
from aprsd import config, fuzzyclock, plugin, plugin_utils, trace
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
@ -64,7 +64,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
|
||||
|
||||
# get last location of a callsign, get descriptive name from weather service
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
@ -95,7 +95,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
|
||||
lon = aprs_data["entries"][0]["lng"]
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, "opencagedata", "apiKey")
|
||||
config.check_config_option(self.config, "opencagedata", "apiKey")
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config opencage:apiKey {ex}")
|
||||
return "No opencage apiKey found"
|
||||
@ -130,7 +130,7 @@ class TimeOWMPlugin(TimePlugin):
|
||||
|
||||
# get last location of a callsign, get descriptive name from weather service
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
@ -160,7 +160,7 @@ class TimeOWMPlugin(TimePlugin):
|
||||
lon = aprs_data["entries"][0]["lng"]
|
||||
|
||||
try:
|
||||
utils.check_config_option(
|
||||
config.check_config_option(
|
||||
self.config,
|
||||
["services", "openweathermap", "apiKey"],
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ import re
|
||||
|
||||
import requests
|
||||
|
||||
from aprsd import plugin, plugin_utils, trace, utils
|
||||
from aprsd import config, plugin, plugin_utils, trace
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
@ -34,7 +34,7 @@ class USWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
# message = packet.get("message_text", None)
|
||||
# ack = packet.get("msgNo", "0")
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
@ -115,7 +115,7 @@ class USMetarPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
fromcall = fromcall
|
||||
|
||||
try:
|
||||
utils.check_config_option(
|
||||
config.check_config_option(
|
||||
self.config,
|
||||
["services", "aprs.fi", "apiKey"],
|
||||
)
|
||||
@ -199,7 +199,7 @@ class OWMWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
searchcall = fromcall
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
@ -220,7 +220,7 @@ class OWMWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
lon = aprs_data["entries"][0]["lng"]
|
||||
|
||||
try:
|
||||
utils.check_config_option(
|
||||
config.check_config_option(
|
||||
self.config,
|
||||
["services", "openweathermap", "apiKey"],
|
||||
)
|
||||
@ -229,7 +229,7 @@ class OWMWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
return "No openweathermap apiKey found"
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, ["aprsd", "units"])
|
||||
config.check_config_option(self.config, ["aprsd", "units"])
|
||||
except Exception:
|
||||
LOG.debug("Couldn't find untis in aprsd:services:units")
|
||||
units = "metric"
|
||||
@ -323,7 +323,7 @@ class AVWXWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
searchcall = fromcall
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
|
||||
return "No aprs.fi apikey found"
|
||||
@ -344,13 +344,13 @@ class AVWXWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||
lon = aprs_data["entries"][0]["lng"]
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "avwx", "apiKey"])
|
||||
config.check_config_option(self.config, ["services", "avwx", "apiKey"])
|
||||
except Exception as ex:
|
||||
LOG.error(f"Failed to find config avwx:apiKey {ex}")
|
||||
return "No avwx apiKey found"
|
||||
|
||||
try:
|
||||
utils.check_config_option(self.config, ["services", "avwx", "base_url"])
|
||||
config.check_config_option(self.config, ["services", "avwx", "base_url"])
|
||||
except Exception as ex:
|
||||
LOG.debug(f"Didn't find avwx:base_url {ex}")
|
||||
base_url = "https://avwx.rest"
|
||||
|
348
aprsd/utils.py
348
aprsd/utils.py
@ -3,128 +3,13 @@
|
||||
import collections
|
||||
import errno
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
|
||||
import click
|
||||
import update_checker
|
||||
import yaml
|
||||
|
||||
import aprsd
|
||||
from aprsd import plugin
|
||||
|
||||
|
||||
LOG_LEVELS = {
|
||||
"CRITICAL": logging.CRITICAL,
|
||||
"ERROR": logging.ERROR,
|
||||
"WARNING": logging.WARNING,
|
||||
"INFO": logging.INFO,
|
||||
"DEBUG": logging.DEBUG,
|
||||
}
|
||||
|
||||
DEFAULT_DATE_FORMAT = "%m/%d/%Y %I:%M:%S %p"
|
||||
DEFAULT_LOG_FORMAT = (
|
||||
"[%(asctime)s] [%(threadName)-20.20s] [%(levelname)-5.5s]"
|
||||
" %(message)s - [%(pathname)s:%(lineno)d]"
|
||||
)
|
||||
|
||||
QUEUE_DATE_FORMAT = "[%m/%d/%Y] [%I:%M:%S %p]"
|
||||
QUEUE_LOG_FORMAT = (
|
||||
"%(asctime)s [%(threadName)-20.20s] [%(levelname)-5.5s]"
|
||||
" %(message)s - [%(pathname)s:%(lineno)d]"
|
||||
)
|
||||
|
||||
# an example of what should be in the ~/.aprsd/config.yml
|
||||
DEFAULT_CONFIG_DICT = {
|
||||
"ham": {"callsign": "NOCALL"},
|
||||
"aprs": {
|
||||
"enabled": True,
|
||||
"login": "CALLSIGN",
|
||||
"password": "00000",
|
||||
"host": "rotate.aprs2.net",
|
||||
"port": 14580,
|
||||
},
|
||||
"kiss": {
|
||||
"tcp": {
|
||||
"enabled": False,
|
||||
"host": "direwolf.ip.address",
|
||||
"port": "8001",
|
||||
},
|
||||
"serial": {
|
||||
"enabled": False,
|
||||
"device": "/dev/ttyS0",
|
||||
"baudrate": 9600,
|
||||
},
|
||||
},
|
||||
"aprsd": {
|
||||
"logfile": "/tmp/aprsd.log",
|
||||
"logformat": DEFAULT_LOG_FORMAT,
|
||||
"dateformat": DEFAULT_DATE_FORMAT,
|
||||
"trace": False,
|
||||
"enabled_plugins": plugin.CORE_MESSAGE_PLUGINS,
|
||||
"units": "imperial",
|
||||
"watch_list": {
|
||||
"enabled": False,
|
||||
# Who gets the alert?
|
||||
"alert_callsign": "NOCALL",
|
||||
# 43200 is 12 hours
|
||||
"alert_time_seconds": 43200,
|
||||
# How many packets to save in a ring Buffer
|
||||
# for a particular callsign
|
||||
"packet_keep_count": 10,
|
||||
"callsigns": [],
|
||||
"enabled_plugins": plugin.CORE_NOTIFY_PLUGINS,
|
||||
},
|
||||
"web": {
|
||||
"enabled": True,
|
||||
"logging_enabled": True,
|
||||
"host": "0.0.0.0",
|
||||
"port": 8001,
|
||||
"users": {
|
||||
"admin": "password-here",
|
||||
},
|
||||
},
|
||||
"email": {
|
||||
"enabled": True,
|
||||
"shortcuts": {
|
||||
"aa": "5551239999@vtext.com",
|
||||
"cl": "craiglamparter@somedomain.org",
|
||||
"wb": "555309@vtext.com",
|
||||
},
|
||||
"smtp": {
|
||||
"login": "SMTP_USERNAME",
|
||||
"password": "SMTP_PASSWORD",
|
||||
"host": "smtp.gmail.com",
|
||||
"port": 465,
|
||||
"use_ssl": False,
|
||||
"debug": False,
|
||||
},
|
||||
"imap": {
|
||||
"login": "IMAP_USERNAME",
|
||||
"password": "IMAP_PASSWORD",
|
||||
"host": "imap.gmail.com",
|
||||
"port": 993,
|
||||
"use_ssl": True,
|
||||
"debug": False,
|
||||
},
|
||||
},
|
||||
},
|
||||
"services": {
|
||||
"aprs.fi": {"apiKey": "APIKEYVALUE"},
|
||||
"openweathermap": {"apiKey": "APIKEYVALUE"},
|
||||
"opencagedata": {"apiKey": "APIKEYVALUE"},
|
||||
"avwx": {"base_url": "http://host:port", "apiKey": "APIKEYVALUE"},
|
||||
},
|
||||
}
|
||||
|
||||
home = str(Path.home())
|
||||
DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/"
|
||||
DEFAULT_SAVE_FILE = f"{home}/.config/aprsd/aprsd.p"
|
||||
DEFAULT_CONFIG_FILE = f"{home}/.config/aprsd/aprsd.yml"
|
||||
|
||||
|
||||
def synchronized(wrapped):
|
||||
@ -175,239 +60,6 @@ def end_substr(original, substr):
|
||||
return idx
|
||||
|
||||
|
||||
def dump_default_cfg():
|
||||
return add_config_comments(
|
||||
yaml.dump(
|
||||
DEFAULT_CONFIG_DICT,
|
||||
indent=4,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def add_config_comments(raw_yaml):
|
||||
end_idx = end_substr(raw_yaml, "aprs:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = insert_str(
|
||||
raw_yaml,
|
||||
"\n # Set enabled to False if there is no internet connectivity."
|
||||
"\n # This is useful for a direwolf KISS aprs connection only. "
|
||||
"\n"
|
||||
"\n # Get the passcode for your callsign here: "
|
||||
"\n # https://apps.magicbug.co.uk/passcode",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = end_substr(raw_yaml, "aprs.fi:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = insert_str(
|
||||
raw_yaml,
|
||||
"\n # Get the apiKey from your aprs.fi account here: "
|
||||
"\n # http://aprs.fi/account",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = end_substr(raw_yaml, "opencagedata:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for TimeOpenCageDataPlugin) "
|
||||
"\n # Get the apiKey from your opencagedata account here: "
|
||||
"\n # https://opencagedata.com/dashboard#api-keys",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = end_substr(raw_yaml, "openweathermap:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for OWMWeatherPlugin) "
|
||||
"\n # Get the apiKey from your "
|
||||
"\n # openweathermap account here: "
|
||||
"\n # https://home.openweathermap.org/api_keys",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
end_idx = end_substr(raw_yaml, "avwx:")
|
||||
if end_idx != -1:
|
||||
# lets insert a comment
|
||||
raw_yaml = insert_str(
|
||||
raw_yaml,
|
||||
"\n # (Optional for AVWXWeatherPlugin) "
|
||||
"\n # Use hosted avwx-api here: https://avwx.rest "
|
||||
"\n # or deploy your own from here: "
|
||||
"\n # https://github.com/avwx-rest/avwx-api",
|
||||
end_idx,
|
||||
)
|
||||
|
||||
return raw_yaml
|
||||
|
||||
|
||||
def create_default_config():
|
||||
"""Create a default config file."""
|
||||
# make sure the directory location exists
|
||||
config_file_expanded = os.path.expanduser(DEFAULT_CONFIG_FILE)
|
||||
config_dir = os.path.dirname(config_file_expanded)
|
||||
if not os.path.exists(config_dir):
|
||||
click.echo(f"Config dir '{config_dir}' doesn't exist, creating.")
|
||||
mkdir_p(config_dir)
|
||||
with open(config_file_expanded, "w+") as cf:
|
||||
cf.write(dump_default_cfg())
|
||||
|
||||
|
||||
def get_config(config_file):
|
||||
"""This tries to read the yaml config from <config_file>."""
|
||||
config_file_expanded = os.path.expanduser(config_file)
|
||||
if os.path.exists(config_file_expanded):
|
||||
with open(config_file_expanded) as stream:
|
||||
config = yaml.load(stream, Loader=yaml.FullLoader)
|
||||
return config
|
||||
else:
|
||||
if config_file == DEFAULT_CONFIG_FILE:
|
||||
click.echo(
|
||||
f"{config_file_expanded} is missing, creating config file",
|
||||
)
|
||||
create_default_config()
|
||||
msg = (
|
||||
"Default config file created at {}. Please edit with your "
|
||||
"settings.".format(config_file)
|
||||
)
|
||||
click.echo(msg)
|
||||
else:
|
||||
# The user provided a config file path different from the
|
||||
# Default, so we won't try and create it, just bitch and bail.
|
||||
msg = f"Custom config file '{config_file}' is missing."
|
||||
click.echo(msg)
|
||||
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def conf_option_exists(conf, chain):
|
||||
_key = chain.pop(0)
|
||||
if _key in conf:
|
||||
return conf_option_exists(conf[_key], chain) if chain else conf[_key]
|
||||
|
||||
|
||||
def check_config_option(config, chain, default_fail=None):
|
||||
result = conf_option_exists(config, chain.copy())
|
||||
if result is None:
|
||||
raise Exception(
|
||||
"'{}' was not in config file".format(
|
||||
chain,
|
||||
),
|
||||
)
|
||||
else:
|
||||
if default_fail:
|
||||
if result == default_fail:
|
||||
# We have to fail and bail if the user hasn't edited
|
||||
# this config option.
|
||||
raise Exception(
|
||||
"Config file needs to be edited from provided defaults for {}.".format(
|
||||
chain,
|
||||
),
|
||||
)
|
||||
else:
|
||||
return config
|
||||
|
||||
|
||||
# This method tries to parse the config yaml file
|
||||
# and consume the settings.
|
||||
# If the required params don't exist,
|
||||
# it will look in the environment
|
||||
def parse_config(config_file):
|
||||
# for now we still use globals....ugh
|
||||
global CONFIG
|
||||
|
||||
def fail(msg):
|
||||
click.echo(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
def check_option(config, chain, default_fail=None):
|
||||
try:
|
||||
config = check_config_option(config, chain, default_fail=default_fail)
|
||||
except Exception as ex:
|
||||
fail(repr(ex))
|
||||
else:
|
||||
return config
|
||||
|
||||
config = get_config(config_file)
|
||||
|
||||
# special check here to make sure user has edited the config file
|
||||
# and changed the ham callsign
|
||||
check_option(
|
||||
config,
|
||||
[
|
||||
"ham",
|
||||
"callsign",
|
||||
],
|
||||
default_fail=DEFAULT_CONFIG_DICT["ham"]["callsign"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["services", "aprs.fi", "apiKey"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["services"]["aprs.fi"]["apiKey"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprs", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprs"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprs", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprs"]["password"],
|
||||
)
|
||||
|
||||
# Ensure they change the admin password
|
||||
if config["aprsd"]["web"]["enabled"] is True:
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "web", "users", "admin"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["web"]["users"]["admin"],
|
||||
)
|
||||
|
||||
if config["aprsd"]["watch_list"]["enabled"] is True:
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "watch_list", "alert_callsign"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["watch_list"]["alert_callsign"],
|
||||
)
|
||||
|
||||
if config["aprsd"]["email"]["enabled"] is True:
|
||||
# Check IMAP server settings
|
||||
check_option(config, ["aprsd", "email", "imap", "host"])
|
||||
check_option(config, ["aprsd", "email", "imap", "port"])
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "imap", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["imap"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "imap", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["imap"]["password"],
|
||||
)
|
||||
|
||||
# Check SMTP server settings
|
||||
check_option(config, ["aprsd", "email", "smtp", "host"])
|
||||
check_option(config, ["aprsd", "email", "smtp", "port"])
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "smtp", "login"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["smtp"]["login"],
|
||||
)
|
||||
check_option(
|
||||
config,
|
||||
["aprsd", "email", "smtp", "password"],
|
||||
default_fail=DEFAULT_CONFIG_DICT["aprsd"]["email"]["smtp"]["password"],
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def human_size(bytes, units=None):
|
||||
"""Returns a human readable string representation of bytes"""
|
||||
if not units:
|
||||
|
@ -28,7 +28,7 @@ RUN addgroup --gid $GID $APRS_USER
|
||||
RUN useradd -m -u $UID -g $APRS_USER $APRS_USER
|
||||
|
||||
# Install aprsd
|
||||
RUN /usr/local/bin/pip3 install aprsd==2.3.0
|
||||
RUN /usr/local/bin/pip3 install aprsd==2.3.1
|
||||
|
||||
# Ensure /config is there with a default config file
|
||||
USER root
|
||||
|
@ -36,7 +36,7 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
VERSION="2.2.1"
|
||||
VERSION="2.3.1"
|
||||
|
||||
if [ $ALL_PLATFORMS -eq 1 ]
|
||||
then
|
||||
|
@ -4,7 +4,7 @@ from unittest import mock
|
||||
import pytz
|
||||
|
||||
import aprsd
|
||||
from aprsd import messaging, packets, stats, utils
|
||||
from aprsd import config, messaging, packets, stats
|
||||
from aprsd.fuzzyclock import fuzzy
|
||||
from aprsd.plugins import fortune as fortune_plugin
|
||||
from aprsd.plugins import ping as ping_plugin
|
||||
@ -19,7 +19,7 @@ class TestPlugin(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.fromcall = fake.FAKE_FROM_CALLSIGN
|
||||
self.ack = 1
|
||||
self.config = utils.DEFAULT_CONFIG_DICT
|
||||
self.config = config.DEFAULT_CONFIG_DICT
|
||||
self.config["ham"]["callsign"] = self.fromcall
|
||||
self.config["aprs"]["login"] = fake.FAKE_TO_CALLSIGN
|
||||
# Inintialize the stats object with the config
|
||||
|
Loading…
Reference in New Issue
Block a user