mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-15 12:51:57 -05:00
Reworked all the common arguments
This patch reworks all the common arguments for the commands and subcommands --loglevel --config_file --quiet These are all now processed in 1 place.
This commit is contained in:
parent
617973f561
commit
89727e2b8e
@ -22,8 +22,6 @@
|
||||
# python included libs
|
||||
import datetime
|
||||
import logging
|
||||
from logging import NullHandler
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
@ -36,7 +34,7 @@ import click_completion
|
||||
import aprsd
|
||||
from aprsd import cli_helper
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import messaging, packets, stats, threads, utils
|
||||
from aprsd import log, messaging, packets, stats, threads, utils
|
||||
|
||||
|
||||
# setup the global logger
|
||||
@ -56,52 +54,17 @@ def custom_startswith(string, incomplete):
|
||||
|
||||
click_completion.core.startswith = custom_startswith
|
||||
click_completion.init()
|
||||
cli_initialized = 0
|
||||
|
||||
|
||||
@click.group(cls=cli_helper.GroupWithCommandOptions, context_settings=CONTEXT_SETTINGS)
|
||||
@click.option(
|
||||
"--loglevel",
|
||||
default="INFO",
|
||||
show_default=True,
|
||||
type=click.Choice(
|
||||
["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"],
|
||||
case_sensitive=False,
|
||||
),
|
||||
show_choices=True,
|
||||
help="The log level to use for aprsd.log",
|
||||
)
|
||||
@click.option(
|
||||
"-c",
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
)
|
||||
@click.option(
|
||||
"--quiet",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Don't log to stdout",
|
||||
)
|
||||
@click.group(context_settings=CONTEXT_SETTINGS)
|
||||
@click.version_option()
|
||||
@click.pass_context
|
||||
def cli(ctx, loglevel, config_file, quiet):
|
||||
global cli_initialized
|
||||
# Have to do the global crap because the cli_helper GroupWithCommandOptions
|
||||
# ends up calling this twice.
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj["loglevel"] = loglevel
|
||||
ctx.obj["config_file"] = config_file
|
||||
ctx.obj["quiet"] = quiet
|
||||
ctx.obj["config"] = aprsd_config.parse_config(config_file)
|
||||
if not cli_initialized:
|
||||
setup_logging(ctx.obj["config"], loglevel, quiet)
|
||||
cli_initialized = 1
|
||||
def cli(ctx):
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
# First import all the possible commands for the CLI
|
||||
from .cmds import ( # noqa
|
||||
completion, dev, healthcheck, listen, send_message, server,
|
||||
)
|
||||
@ -130,57 +93,17 @@ def signal_handler(sig, frame):
|
||||
signal.signal(signal.SIGTERM, sys.exit(0))
|
||||
|
||||
|
||||
# Setup the logging faciility
|
||||
# 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 = aprsd_config.LOG_LEVELS[loglevel]
|
||||
LOG.setLevel(log_level)
|
||||
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:
|
||||
fh = RotatingFileHandler(log_file, maxBytes=(10248576 * 5), backupCount=4)
|
||||
else:
|
||||
fh = NullHandler()
|
||||
|
||||
fh.setFormatter(log_formatter)
|
||||
LOG.addHandler(fh)
|
||||
|
||||
imap_logger = None
|
||||
if config.get("aprsd.email.enabled", default=False) and config.get("aprsd.email.imap.debug", default=False):
|
||||
|
||||
imap_logger = logging.getLogger("imapclient.imaplib")
|
||||
imap_logger.setLevel(log_level)
|
||||
imap_logger.addHandler(fh)
|
||||
|
||||
if config.get("aprsd.web.enabled", default=False):
|
||||
qh = logging.handlers.QueueHandler(threads.logging_queue)
|
||||
q_log_formatter = logging.Formatter(
|
||||
fmt=aprsd_config.QUEUE_LOG_FORMAT,
|
||||
datefmt=aprsd_config.QUEUE_DATE_FORMAT,
|
||||
)
|
||||
qh.setFormatter(q_log_formatter)
|
||||
LOG.addHandler(qh)
|
||||
|
||||
if not quiet:
|
||||
sh = logging.StreamHandler(sys.stdout)
|
||||
sh.setFormatter(log_formatter)
|
||||
LOG.addHandler(sh)
|
||||
if imap_logger:
|
||||
imap_logger.addHandler(sh)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def check_version(ctx):
|
||||
"""Check this version against the latest in pypi.org."""
|
||||
config_file = ctx.obj["config_file"]
|
||||
loglevel = ctx.obj["loglevel"]
|
||||
config = aprsd_config.parse_config(config_file)
|
||||
|
||||
setup_logging(config, loglevel, False)
|
||||
log.setup_logging(config, loglevel, False)
|
||||
level, msg = utils._check_version()
|
||||
if level:
|
||||
LOG.warning(msg)
|
||||
|
@ -1,5 +1,73 @@
|
||||
from functools import update_wrapper
|
||||
import typing as t
|
||||
|
||||
import click
|
||||
|
||||
from aprsd import config as aprsd_config
|
||||
from aprsd import log
|
||||
|
||||
|
||||
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
|
||||
|
||||
common_options = [
|
||||
click.option(
|
||||
"--loglevel",
|
||||
default="INFO",
|
||||
show_default=True,
|
||||
type=click.Choice(
|
||||
["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG"],
|
||||
case_sensitive=False,
|
||||
),
|
||||
show_choices=True,
|
||||
help="The log level to use for aprsd.log",
|
||||
),
|
||||
click.option(
|
||||
"-c",
|
||||
"--config",
|
||||
"config_file",
|
||||
show_default=True,
|
||||
default=aprsd_config.DEFAULT_CONFIG_FILE,
|
||||
help="The aprsd config file to use for options.",
|
||||
),
|
||||
click.option(
|
||||
"--quiet",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Don't log to stdout",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def add_options(options):
|
||||
def _add_options(func):
|
||||
for option in reversed(options):
|
||||
func = option(func)
|
||||
return func
|
||||
return _add_options
|
||||
|
||||
|
||||
def process_standard_options(f: F) -> F:
|
||||
def new_func(*args, **kwargs):
|
||||
print(f"ARGS {args}")
|
||||
print(f"KWARGS {kwargs}")
|
||||
ctx = args[0]
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj["loglevel"] = kwargs["loglevel"]
|
||||
ctx.obj["config_file"] = kwargs["config_file"]
|
||||
ctx.obj["quiet"] = kwargs["quiet"]
|
||||
ctx.obj["config"] = aprsd_config.parse_config(kwargs["config_file"])
|
||||
log.setup_logging(
|
||||
ctx.obj["config"], ctx.obj["loglevel"],
|
||||
ctx.obj["quiet"],
|
||||
)
|
||||
|
||||
del kwargs["loglevel"]
|
||||
del kwargs["config_file"]
|
||||
del kwargs["quiet"]
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return update_wrapper(t.cast(F, new_func), f)
|
||||
|
||||
|
||||
class AliasedGroup(click.Group):
|
||||
def command(self, *args, **kwargs):
|
||||
@ -33,42 +101,3 @@ class AliasedGroup(click.Group):
|
||||
self.add_command(cmd, name=alias)
|
||||
return cmd
|
||||
return decorator
|
||||
|
||||
|
||||
class GroupWithCommandOptions(click.Group):
|
||||
""" Allow application of options to group with multi command """
|
||||
|
||||
def add_command(self, cmd, name=None):
|
||||
click.Group.add_command(self, cmd, name=name)
|
||||
|
||||
# add the group parameters to the command
|
||||
for param in self.params:
|
||||
cmd.params.append(param)
|
||||
|
||||
# hook the commands invoke with our own
|
||||
cmd.invoke = self.build_command_invoke(cmd.invoke)
|
||||
self.invoke_without_command = True
|
||||
|
||||
def build_command_invoke(self, original_invoke):
|
||||
|
||||
def command_invoke(ctx):
|
||||
""" insert invocation of group function """
|
||||
|
||||
# separate the group parameters
|
||||
ctx.obj = dict(_params={})
|
||||
for param in self.params:
|
||||
name = param.name
|
||||
if name in ctx.params:
|
||||
ctx.obj["_params"][name] = ctx.params[name]
|
||||
del ctx.params[name]
|
||||
|
||||
# call the group function with its parameters
|
||||
params = ctx.params
|
||||
ctx.params = ctx.obj["_params"]
|
||||
self.invoke(ctx)
|
||||
ctx.params = params
|
||||
|
||||
# now call the original invoke(the command)
|
||||
original_invoke(ctx)
|
||||
|
||||
return command_invoke
|
||||
|
@ -14,7 +14,7 @@ def completion(ctx):
|
||||
|
||||
|
||||
# show dumps out the completion code for a particular shell
|
||||
@completion.command(help="Show completion code for shell")
|
||||
@completion.command(help="Show completion code for shell", name="show")
|
||||
@click.option("-i", "--case-insensitive/--no-case-insensitive", help="Case insensitive completion")
|
||||
@click.argument("shell", required=False, type=click_completion.DocumentedChoice(click_completion.core.shells))
|
||||
def show(shell, case_insensitive):
|
||||
@ -24,7 +24,7 @@ def show(shell, case_insensitive):
|
||||
|
||||
|
||||
# install will install the completion code for a particular shell
|
||||
@completion.command(help="Install completion code for a shell")
|
||||
@completion.command(help="Install completion code for a shell", name="install")
|
||||
@click.option("--append/--overwrite", help="Append the completion code to the file", default=None)
|
||||
@click.option("-i", "--case-insensitive/--no-case-insensitive", help="Case insensitive completion")
|
||||
@click.argument("shell", required=False, type=click_completion.DocumentedChoice(click_completion.core.shells))
|
||||
|
@ -8,7 +8,7 @@ import logging
|
||||
import click
|
||||
|
||||
# local imports here
|
||||
from aprsd import client, plugin
|
||||
from aprsd import cli_helper, client, plugin
|
||||
|
||||
from ..aprsd import cli
|
||||
|
||||
@ -17,7 +17,14 @@ LOG = logging.getLogger("APRSD")
|
||||
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli.group(help="Development type subcommands", context_settings=CONTEXT_SETTINGS)
|
||||
@click.pass_context
|
||||
def dev(ctx):
|
||||
pass
|
||||
|
||||
|
||||
@dev.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--aprs-login",
|
||||
envvar="APRS_LOGIN",
|
||||
@ -51,6 +58,7 @@ CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
)
|
||||
@click.argument("message", nargs=-1, required=True)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def test_plugin(
|
||||
ctx,
|
||||
aprs_login,
|
||||
@ -59,12 +67,7 @@ def test_plugin(
|
||||
number,
|
||||
message,
|
||||
):
|
||||
"""Test an APRSD plugin
|
||||
|
||||
This allows you to develop a plugin and send a 'command' string
|
||||
directly to the plugin during development/testing. Use this before
|
||||
releasing as a plugin for aprsd.
|
||||
"""
|
||||
"""Test an individual APRSD plugin given a python path."""
|
||||
config = ctx.obj["config"]
|
||||
fromcall = aprs_login
|
||||
|
||||
|
@ -13,7 +13,7 @@ import click
|
||||
import requests
|
||||
|
||||
import aprsd
|
||||
from aprsd import utils
|
||||
from aprsd import cli_helper, utils
|
||||
|
||||
# local imports here
|
||||
from ..aprsd import cli
|
||||
@ -25,6 +25,7 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--url",
|
||||
"health_url",
|
||||
@ -39,6 +40,7 @@ LOG = logging.getLogger("APRSD")
|
||||
help="How long to wait for healtcheck url to come back",
|
||||
)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def healthcheck(ctx, health_url, timeout):
|
||||
"""Check the health of the running aprsd server."""
|
||||
ctx.obj["config"]
|
||||
|
@ -13,7 +13,9 @@ import click
|
||||
|
||||
# local imports here
|
||||
import aprsd
|
||||
from aprsd import client, messaging, packets, stats, threads, trace, utils
|
||||
from aprsd import (
|
||||
cli_helper, client, messaging, packets, stats, threads, trace, utils,
|
||||
)
|
||||
|
||||
from ..aprsd import cli
|
||||
|
||||
@ -36,6 +38,7 @@ def signal_handler(sig, frame):
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--aprs-login",
|
||||
envvar="APRS_LOGIN",
|
||||
@ -54,6 +57,7 @@ def signal_handler(sig, frame):
|
||||
required=True,
|
||||
)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def listen(
|
||||
ctx,
|
||||
aprs_login,
|
||||
|
@ -7,7 +7,7 @@ from aprslib.exceptions import LoginError
|
||||
import click
|
||||
|
||||
import aprsd
|
||||
from aprsd import client, messaging, packets
|
||||
from aprsd import cli_helper, client, messaging, packets
|
||||
|
||||
from ..aprsd import cli
|
||||
|
||||
@ -16,6 +16,7 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--aprs-login",
|
||||
envvar="APRS_LOGIN",
|
||||
@ -48,6 +49,7 @@ LOG = logging.getLogger("APRSD")
|
||||
@click.argument("tocallsign", required=True)
|
||||
@click.argument("command", nargs=-1, required=True)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def send_message(
|
||||
ctx,
|
||||
aprs_login,
|
||||
|
@ -6,7 +6,8 @@ import click
|
||||
|
||||
import aprsd
|
||||
from aprsd import (
|
||||
client, flask, messaging, packets, plugin, stats, threads, trace, utils,
|
||||
cli_helper, client, flask, messaging, packets, plugin, stats, threads,
|
||||
trace, utils,
|
||||
)
|
||||
from aprsd import aprsd as aprsd_main
|
||||
|
||||
@ -18,6 +19,7 @@ LOG = logging.getLogger("APRSD")
|
||||
|
||||
# main() ###
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"-f",
|
||||
"--flush",
|
||||
@ -28,6 +30,7 @@ LOG = logging.getLogger("APRSD")
|
||||
help="Flush out all old aged messages on disk.",
|
||||
)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def server(ctx, flush):
|
||||
"""Start the aprsd server gateway process."""
|
||||
ctx.obj["config_file"]
|
||||
|
53
aprsd/log.py
Normal file
53
aprsd/log.py
Normal file
@ -0,0 +1,53 @@
|
||||
import logging
|
||||
from logging import NullHandler
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import queue
|
||||
import sys
|
||||
|
||||
from aprsd import config as aprsd_config
|
||||
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
logging_queue = queue.Queue()
|
||||
|
||||
|
||||
# Setup the logging faciility
|
||||
# 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 = aprsd_config.LOG_LEVELS[loglevel]
|
||||
LOG.setLevel(log_level)
|
||||
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:
|
||||
fh = RotatingFileHandler(log_file, maxBytes=(10248576 * 5), backupCount=4)
|
||||
else:
|
||||
fh = NullHandler()
|
||||
|
||||
fh.setFormatter(log_formatter)
|
||||
LOG.addHandler(fh)
|
||||
|
||||
imap_logger = None
|
||||
if config.get("aprsd.email.enabled", default=False) and config.get("aprsd.email.imap.debug", default=False):
|
||||
|
||||
imap_logger = logging.getLogger("imapclient.imaplib")
|
||||
imap_logger.setLevel(log_level)
|
||||
imap_logger.addHandler(fh)
|
||||
|
||||
if config.get("aprsd.web.enabled", default=False):
|
||||
qh = logging.handlers.QueueHandler(logging_queue)
|
||||
q_log_formatter = logging.Formatter(
|
||||
fmt=aprsd_config.QUEUE_LOG_FORMAT,
|
||||
datefmt=aprsd_config.QUEUE_DATE_FORMAT,
|
||||
)
|
||||
qh.setFormatter(q_log_formatter)
|
||||
LOG.addHandler(qh)
|
||||
|
||||
if not quiet:
|
||||
sh = logging.StreamHandler(sys.stdout)
|
||||
sh.setFormatter(log_formatter)
|
||||
LOG.addHandler(sh)
|
||||
if imap_logger:
|
||||
imap_logger.addHandler(sh)
|
@ -17,7 +17,6 @@ RX_THREAD = "RX"
|
||||
EMAIL_THREAD = "Email"
|
||||
|
||||
rx_msg_queue = queue.Queue(maxsize=20)
|
||||
logging_queue = queue.Queue()
|
||||
msg_queues = {
|
||||
"rx": rx_msg_queue,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user