mirror of
https://github.com/craigerl/aprsd.git
synced 2025-04-19 09:49:01 -04:00
some cleanup
This commit is contained in:
parent
e4f82d6054
commit
e332d7c9d0
@ -11,7 +11,7 @@ from aprsd.packets import core
|
||||
from aprsd.utils import trace
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger("APRSD")
|
||||
LOG = logging.getLogger('APRSD')
|
||||
|
||||
|
||||
class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
||||
@ -24,12 +24,12 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
||||
path = []
|
||||
|
||||
def __init__(self):
|
||||
LOG.info("Starting APRSDFakeClient client.")
|
||||
self.path = ["WIDE1-1", "WIDE2-1"]
|
||||
LOG.info('Starting APRSDFakeClient client.')
|
||||
self.path = ['WIDE1-1', 'WIDE2-1']
|
||||
|
||||
def stop(self):
|
||||
self.thread_stop = True
|
||||
LOG.info("Shutdown APRSDFakeClient client.")
|
||||
LOG.info('Shutdown APRSDFakeClient client.')
|
||||
|
||||
def is_alive(self):
|
||||
"""If the connection is alive or not."""
|
||||
@ -38,35 +38,31 @@ class APRSDFakeClient(metaclass=trace.TraceWrapperMetaclass):
|
||||
@wrapt.synchronized(lock)
|
||||
def send(self, packet: core.Packet):
|
||||
"""Send an APRS Message object."""
|
||||
LOG.info(f"Sending packet: {packet}")
|
||||
LOG.info(f'Sending packet: {packet}')
|
||||
payload = None
|
||||
if isinstance(packet, core.Packet):
|
||||
packet.prepare()
|
||||
payload = packet.payload.encode("US-ASCII")
|
||||
if packet.path:
|
||||
packet.path
|
||||
else:
|
||||
self.path
|
||||
payload = packet.payload.encode('US-ASCII')
|
||||
else:
|
||||
msg_payload = f"{packet.raw}{{{str(packet.msgNo)}"
|
||||
msg_payload = f'{packet.raw}{{{str(packet.msgNo)}'
|
||||
payload = (
|
||||
":{:<9}:{}".format(
|
||||
':{:<9}:{}'.format(
|
||||
packet.to_call,
|
||||
msg_payload,
|
||||
)
|
||||
).encode("US-ASCII")
|
||||
).encode('US-ASCII')
|
||||
|
||||
LOG.debug(
|
||||
f"FAKE::Send '{payload}' TO '{packet.to_call}' From "
|
||||
f"'{packet.from_call}' with PATH \"{self.path}\"",
|
||||
f'\'{packet.from_call}\' with PATH "{self.path}"',
|
||||
)
|
||||
|
||||
def consumer(self, callback, blocking=False, immortal=False, raw=False):
|
||||
LOG.debug("Start non blocking FAKE consumer")
|
||||
LOG.debug('Start non blocking FAKE consumer')
|
||||
# Generate packets here?
|
||||
raw = "GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW"
|
||||
raw = 'GTOWN>APDW16,WIDE1-1,WIDE2-1:}KM6LYW-9>APZ100,TCPIP,GTOWN*::KM6LYW :KM6LYW: 19 Miles SW'
|
||||
pkt_raw = aprslib.parse(raw)
|
||||
pkt = core.factory(pkt_raw)
|
||||
callback(packet=pkt)
|
||||
LOG.debug(f"END blocking FAKE consumer {self}")
|
||||
LOG.debug(f'END blocking FAKE consumer {self}')
|
||||
time.sleep(8)
|
||||
|
@ -16,11 +16,11 @@ from aprsd.main import cli
|
||||
from aprsd.utils import trace
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger("APRSD")
|
||||
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
LOG = logging.getLogger('APRSD')
|
||||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
||||
|
||||
|
||||
@cli.group(help="Development type subcommands", context_settings=CONTEXT_SETTINGS)
|
||||
@cli.group(help='Development type subcommands', context_settings=CONTEXT_SETTINGS)
|
||||
@click.pass_context
|
||||
def dev(ctx):
|
||||
pass
|
||||
@ -29,37 +29,37 @@ def dev(ctx):
|
||||
@dev.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--aprs-login",
|
||||
envvar="APRS_LOGIN",
|
||||
'--aprs-login',
|
||||
envvar='APRS_LOGIN',
|
||||
show_envvar=True,
|
||||
help="What callsign to send the message from.",
|
||||
help='What callsign to send the message from.',
|
||||
)
|
||||
@click.option(
|
||||
"-p",
|
||||
"--plugin",
|
||||
"plugin_path",
|
||||
'-p',
|
||||
'--plugin',
|
||||
'plugin_path',
|
||||
show_default=True,
|
||||
default=None,
|
||||
help="The plugin to run. Ex: aprsd.plugins.ping.PingPlugin",
|
||||
help='The plugin to run. Ex: aprsd.plugins.ping.PingPlugin',
|
||||
)
|
||||
@click.option(
|
||||
"-a",
|
||||
"--all",
|
||||
"load_all",
|
||||
'-a',
|
||||
'--all',
|
||||
'load_all',
|
||||
show_default=True,
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Load all the plugins in config?",
|
||||
help='Load all the plugins in config?',
|
||||
)
|
||||
@click.option(
|
||||
"-n",
|
||||
"--num",
|
||||
"number",
|
||||
'-n',
|
||||
'--num',
|
||||
'number',
|
||||
show_default=True,
|
||||
default=1,
|
||||
help="Number of times to call the plugin",
|
||||
help='Number of times to call the plugin',
|
||||
)
|
||||
@click.argument("message", nargs=-1, required=True)
|
||||
@click.argument('message', nargs=-1, required=True)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def test_plugin(
|
||||
@ -76,7 +76,7 @@ def test_plugin(
|
||||
|
||||
if not aprs_login:
|
||||
if CONF.aprs_network.login == conf.client.DEFAULT_LOGIN:
|
||||
click.echo("Must set --aprs_login or APRS_LOGIN")
|
||||
click.echo('Must set --aprs_login or APRS_LOGIN')
|
||||
ctx.exit(-1)
|
||||
return
|
||||
else:
|
||||
@ -86,16 +86,16 @@ def test_plugin(
|
||||
|
||||
if not plugin_path:
|
||||
click.echo(ctx.get_help())
|
||||
click.echo("")
|
||||
click.echo("Failed to provide -p option to test a plugin")
|
||||
click.echo('')
|
||||
click.echo('Failed to provide -p option to test a plugin')
|
||||
ctx.exit(-1)
|
||||
return
|
||||
|
||||
if type(message) is tuple:
|
||||
message = " ".join(message)
|
||||
message = ' '.join(message)
|
||||
|
||||
if CONF.trace_enabled:
|
||||
trace.setup_tracing(["method", "api"])
|
||||
trace.setup_tracing(['method', 'api'])
|
||||
|
||||
base.APRSClient()
|
||||
|
||||
@ -105,13 +105,13 @@ def test_plugin(
|
||||
obj = pm._create_class(plugin_path, plugin.APRSDPluginBase)
|
||||
if not obj:
|
||||
click.echo(ctx.get_help())
|
||||
click.echo("")
|
||||
click.echo('')
|
||||
ctx.fail(f"Failed to create object from plugin path '{plugin_path}'")
|
||||
ctx.exit()
|
||||
|
||||
# Register the plugin they wanted tested.
|
||||
LOG.info(
|
||||
"Testing plugin {} Version {}".format(
|
||||
'Testing plugin {} Version {}'.format(
|
||||
obj.__class__,
|
||||
obj.version,
|
||||
),
|
||||
@ -126,7 +126,7 @@ def test_plugin(
|
||||
)
|
||||
LOG.info(f"P'{plugin_path}' F'{fromcall}' C'{message}'")
|
||||
|
||||
for x in range(number):
|
||||
for _ in range(number):
|
||||
replies = pm.run(packet)
|
||||
# Plugin might have threads, so lets stop them so we can exit.
|
||||
# obj.stop_threads()
|
||||
@ -147,17 +147,12 @@ def test_plugin(
|
||||
elif isinstance(reply, packets.Packet):
|
||||
# We have a message based object.
|
||||
LOG.info(reply)
|
||||
else:
|
||||
# A plugin can return a null message flag which signals
|
||||
# us that they processed the message correctly, but have
|
||||
# nothing to reply with, so we avoid replying with a
|
||||
# usage string
|
||||
if reply is not packets.NULL_MESSAGE:
|
||||
LOG.info(
|
||||
packets.MessagePacket(
|
||||
from_call=CONF.callsign,
|
||||
to_call=fromcall,
|
||||
message_text=reply,
|
||||
),
|
||||
)
|
||||
elif reply is not packets.NULL_MESSAGE:
|
||||
LOG.info(
|
||||
packets.MessagePacket(
|
||||
from_call=CONF.callsign,
|
||||
to_call=fromcall,
|
||||
message_text=reply,
|
||||
),
|
||||
)
|
||||
pm.stop()
|
||||
|
@ -15,30 +15,30 @@ from aprsd.threads.stats import StatsStore
|
||||
|
||||
# setup the global logger
|
||||
# log.basicConfig(level=log.DEBUG) # level=10
|
||||
LOG = logging.getLogger("APRSD")
|
||||
LOG = logging.getLogger('APRSD')
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--host",
|
||||
'--host',
|
||||
type=str,
|
||||
default=None,
|
||||
help="IP address of the remote aprsd admin web ui fetch stats from.",
|
||||
help='IP address of the remote aprsd admin web ui fetch stats from.',
|
||||
)
|
||||
@click.option(
|
||||
"--port",
|
||||
'--port',
|
||||
type=int,
|
||||
default=None,
|
||||
help="Port of the remote aprsd web admin interface to fetch stats from.",
|
||||
help='Port of the remote aprsd web admin interface to fetch stats from.',
|
||||
)
|
||||
@click.pass_context
|
||||
@cli_helper.process_standard_options
|
||||
def fetch_stats(ctx, host, port):
|
||||
"""Fetch stats from a APRSD admin web interface."""
|
||||
console = Console()
|
||||
console.print(f"APRSD Fetch-Stats started version: {aprsd.__version__}")
|
||||
console.print(f'APRSD Fetch-Stats started version: {aprsd.__version__}')
|
||||
|
||||
CONF.log_opt_values(LOG, logging.DEBUG)
|
||||
if not host:
|
||||
@ -46,114 +46,110 @@ def fetch_stats(ctx, host, port):
|
||||
if not port:
|
||||
port = CONF.admin.web_port
|
||||
|
||||
msg = f"Fetching stats from {host}:{port}"
|
||||
msg = f'Fetching stats from {host}:{port}'
|
||||
console.print(msg)
|
||||
with console.status(msg):
|
||||
response = requests.get(f"http://{host}:{port}/stats", timeout=120)
|
||||
response = requests.get(f'http://{host}:{port}/stats', timeout=120)
|
||||
if not response:
|
||||
console.print(
|
||||
f"Failed to fetch stats from {host}:{port}?",
|
||||
style="bold red",
|
||||
f'Failed to fetch stats from {host}:{port}?',
|
||||
style='bold red',
|
||||
)
|
||||
return
|
||||
|
||||
stats = response.json()
|
||||
if not stats:
|
||||
console.print(
|
||||
f"Failed to fetch stats from aprsd admin ui at {host}:{port}",
|
||||
style="bold red",
|
||||
f'Failed to fetch stats from aprsd admin ui at {host}:{port}',
|
||||
style='bold red',
|
||||
)
|
||||
return
|
||||
|
||||
aprsd_title = (
|
||||
"APRSD "
|
||||
f"[bold cyan]v{stats['APRSDStats']['version']}[/] "
|
||||
f"Callsign [bold green]{stats['APRSDStats']['callsign']}[/] "
|
||||
f"Uptime [bold yellow]{stats['APRSDStats']['uptime']}[/]"
|
||||
'APRSD '
|
||||
f'[bold cyan]v{stats["APRSDStats"]["version"]}[/] '
|
||||
f'Callsign [bold green]{stats["APRSDStats"]["callsign"]}[/] '
|
||||
f'Uptime [bold yellow]{stats["APRSDStats"]["uptime"]}[/]'
|
||||
)
|
||||
|
||||
console.rule(f"Stats from {host}:{port}")
|
||||
console.print("\n\n")
|
||||
console.rule(f'Stats from {host}:{port}')
|
||||
console.print('\n\n')
|
||||
console.rule(aprsd_title)
|
||||
|
||||
# Show the connection to APRS
|
||||
# It can be a connection to an APRS-IS server or a local TNC via KISS or KISSTCP
|
||||
if "aprs-is" in stats:
|
||||
title = f"APRS-IS Connection {stats['APRSClientStats']['server_string']}"
|
||||
if 'aprs-is' in stats:
|
||||
title = f'APRS-IS Connection {stats["APRSClientStats"]["server_string"]}'
|
||||
table = Table(title=title)
|
||||
table.add_column("Key")
|
||||
table.add_column("Value")
|
||||
for key, value in stats["APRSClientStats"].items():
|
||||
table.add_column('Key')
|
||||
table.add_column('Value')
|
||||
for key, value in stats['APRSClientStats'].items():
|
||||
table.add_row(key, value)
|
||||
console.print(table)
|
||||
|
||||
threads_table = Table(title="Threads")
|
||||
threads_table.add_column("Name")
|
||||
threads_table.add_column("Alive?")
|
||||
for name, alive in stats["APRSDThreadList"].items():
|
||||
threads_table = Table(title='Threads')
|
||||
threads_table.add_column('Name')
|
||||
threads_table.add_column('Alive?')
|
||||
for name, alive in stats['APRSDThreadList'].items():
|
||||
threads_table.add_row(name, str(alive))
|
||||
|
||||
console.print(threads_table)
|
||||
|
||||
packet_totals = Table(title="Packet Totals")
|
||||
packet_totals.add_column("Key")
|
||||
packet_totals.add_column("Value")
|
||||
packet_totals.add_row("Total Received", str(stats["PacketList"]["rx"]))
|
||||
packet_totals.add_row("Total Sent", str(stats["PacketList"]["tx"]))
|
||||
packet_totals = Table(title='Packet Totals')
|
||||
packet_totals.add_column('Key')
|
||||
packet_totals.add_column('Value')
|
||||
packet_totals.add_row('Total Received', str(stats['PacketList']['rx']))
|
||||
packet_totals.add_row('Total Sent', str(stats['PacketList']['tx']))
|
||||
console.print(packet_totals)
|
||||
|
||||
# Show each of the packet types
|
||||
packets_table = Table(title="Packets By Type")
|
||||
packets_table.add_column("Packet Type")
|
||||
packets_table.add_column("TX")
|
||||
packets_table.add_column("RX")
|
||||
for key, value in stats["PacketList"]["packets"].items():
|
||||
packets_table.add_row(key, str(value["tx"]), str(value["rx"]))
|
||||
packets_table = Table(title='Packets By Type')
|
||||
packets_table.add_column('Packet Type')
|
||||
packets_table.add_column('TX')
|
||||
packets_table.add_column('RX')
|
||||
for key, value in stats['PacketList']['packets'].items():
|
||||
packets_table.add_row(key, str(value['tx']), str(value['rx']))
|
||||
|
||||
console.print(packets_table)
|
||||
|
||||
if "plugins" in stats:
|
||||
count = len(stats["PluginManager"])
|
||||
plugins_table = Table(title=f"Plugins ({count})")
|
||||
plugins_table.add_column("Plugin")
|
||||
plugins_table.add_column("Enabled")
|
||||
plugins_table.add_column("Version")
|
||||
plugins_table.add_column("TX")
|
||||
plugins_table.add_column("RX")
|
||||
plugins = stats["PluginManager"]
|
||||
for key, value in plugins.items():
|
||||
if 'plugins' in stats:
|
||||
count = len(stats['PluginManager'])
|
||||
plugins_table = Table(title=f'Plugins ({count})')
|
||||
plugins_table.add_column('Plugin')
|
||||
plugins_table.add_column('Enabled')
|
||||
plugins_table.add_column('Version')
|
||||
plugins_table.add_column('TX')
|
||||
plugins_table.add_column('RX')
|
||||
plugins = stats['PluginManager']
|
||||
for key, _ in plugins.items():
|
||||
plugins_table.add_row(
|
||||
key,
|
||||
str(plugins[key]["enabled"]),
|
||||
plugins[key]["version"],
|
||||
str(plugins[key]["tx"]),
|
||||
str(plugins[key]["rx"]),
|
||||
str(plugins[key]['enabled']),
|
||||
plugins[key]['version'],
|
||||
str(plugins[key]['tx']),
|
||||
str(plugins[key]['rx']),
|
||||
)
|
||||
|
||||
console.print(plugins_table)
|
||||
|
||||
seen_list = stats.get("SeenList")
|
||||
|
||||
if seen_list:
|
||||
if seen_list := stats.get('SeenList'):
|
||||
count = len(seen_list)
|
||||
seen_table = Table(title=f"Seen List ({count})")
|
||||
seen_table.add_column("Callsign")
|
||||
seen_table.add_column("Message Count")
|
||||
seen_table.add_column("Last Heard")
|
||||
seen_table = Table(title=f'Seen List ({count})')
|
||||
seen_table.add_column('Callsign')
|
||||
seen_table.add_column('Message Count')
|
||||
seen_table.add_column('Last Heard')
|
||||
for key, value in seen_list.items():
|
||||
seen_table.add_row(key, str(value["count"]), value["last"])
|
||||
seen_table.add_row(key, str(value['count']), value['last'])
|
||||
|
||||
console.print(seen_table)
|
||||
|
||||
watch_list = stats.get("WatchList")
|
||||
|
||||
if watch_list:
|
||||
if watch_list := stats.get('WatchList'):
|
||||
count = len(watch_list)
|
||||
watch_table = Table(title=f"Watch List ({count})")
|
||||
watch_table.add_column("Callsign")
|
||||
watch_table.add_column("Last Heard")
|
||||
watch_table = Table(title=f'Watch List ({count})')
|
||||
watch_table.add_column('Callsign')
|
||||
watch_table.add_column('Last Heard')
|
||||
for key, value in watch_list.items():
|
||||
watch_table.add_row(key, value["last"])
|
||||
watch_table.add_row(key, value['last'])
|
||||
|
||||
console.print(watch_table)
|
||||
|
||||
@ -161,27 +157,27 @@ def fetch_stats(ctx, host, port):
|
||||
@cli.command()
|
||||
@cli_helper.add_options(cli_helper.common_options)
|
||||
@click.option(
|
||||
"--raw",
|
||||
'--raw',
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Dump raw stats instead of formatted output.",
|
||||
help='Dump raw stats instead of formatted output.',
|
||||
)
|
||||
@click.option(
|
||||
"--show-section",
|
||||
default=["All"],
|
||||
help="Show specific sections of the stats. "
|
||||
" Choices: All, APRSDStats, APRSDThreadList, APRSClientStats,"
|
||||
" PacketList, SeenList, WatchList",
|
||||
'--show-section',
|
||||
default=['All'],
|
||||
help='Show specific sections of the stats. '
|
||||
' Choices: All, APRSDStats, APRSDThreadList, APRSClientStats,'
|
||||
' PacketList, SeenList, WatchList',
|
||||
multiple=True,
|
||||
type=click.Choice(
|
||||
[
|
||||
"All",
|
||||
"APRSDStats",
|
||||
"APRSDThreadList",
|
||||
"APRSClientStats",
|
||||
"PacketList",
|
||||
"SeenList",
|
||||
"WatchList",
|
||||
'All',
|
||||
'APRSDStats',
|
||||
'APRSDThreadList',
|
||||
'APRSClientStats',
|
||||
'PacketList',
|
||||
'SeenList',
|
||||
'WatchList',
|
||||
],
|
||||
case_sensitive=False,
|
||||
),
|
||||
@ -191,122 +187,122 @@ def fetch_stats(ctx, host, port):
|
||||
def dump_stats(ctx, raw, show_section):
|
||||
"""Dump the current stats from the running APRSD instance."""
|
||||
console = Console()
|
||||
console.print(f"APRSD Dump-Stats started version: {aprsd.__version__}")
|
||||
console.print(f'APRSD Dump-Stats started version: {aprsd.__version__}')
|
||||
|
||||
with console.status("Dumping stats"):
|
||||
with console.status('Dumping stats'):
|
||||
ss = StatsStore()
|
||||
ss.load()
|
||||
stats = ss.data
|
||||
if raw:
|
||||
if "All" in show_section:
|
||||
if 'All' in show_section:
|
||||
console.print(stats)
|
||||
return
|
||||
else:
|
||||
for section in show_section:
|
||||
console.print(f"Dumping {section} section:")
|
||||
console.print(f'Dumping {section} section:')
|
||||
console.print(stats[section])
|
||||
return
|
||||
|
||||
t = Table(title="APRSD Stats")
|
||||
t.add_column("Key")
|
||||
t.add_column("Value")
|
||||
for key, value in stats["APRSDStats"].items():
|
||||
t = Table(title='APRSD Stats')
|
||||
t.add_column('Key')
|
||||
t.add_column('Value')
|
||||
for key, value in stats['APRSDStats'].items():
|
||||
t.add_row(key, str(value))
|
||||
|
||||
if "All" in show_section or "APRSDStats" in show_section:
|
||||
if 'All' in show_section or 'APRSDStats' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# Show the thread list
|
||||
t = Table(title="Thread List")
|
||||
t.add_column("Name")
|
||||
t.add_column("Class")
|
||||
t.add_column("Alive?")
|
||||
t.add_column("Loop Count")
|
||||
t.add_column("Age")
|
||||
for name, value in stats["APRSDThreadList"].items():
|
||||
t = Table(title='Thread List')
|
||||
t.add_column('Name')
|
||||
t.add_column('Class')
|
||||
t.add_column('Alive?')
|
||||
t.add_column('Loop Count')
|
||||
t.add_column('Age')
|
||||
for name, value in stats['APRSDThreadList'].items():
|
||||
t.add_row(
|
||||
name,
|
||||
value["class"],
|
||||
str(value["alive"]),
|
||||
str(value["loop_count"]),
|
||||
str(value["age"]),
|
||||
value['class'],
|
||||
str(value['alive']),
|
||||
str(value['loop_count']),
|
||||
str(value['age']),
|
||||
)
|
||||
|
||||
if "All" in show_section or "APRSDThreadList" in show_section:
|
||||
if 'All' in show_section or 'APRSDThreadList' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# Show the plugins
|
||||
t = Table(title="Plugin List")
|
||||
t.add_column("Name")
|
||||
t.add_column("Enabled")
|
||||
t.add_column("Version")
|
||||
t.add_column("TX")
|
||||
t.add_column("RX")
|
||||
for name, value in stats["PluginManager"].items():
|
||||
t = Table(title='Plugin List')
|
||||
t.add_column('Name')
|
||||
t.add_column('Enabled')
|
||||
t.add_column('Version')
|
||||
t.add_column('TX')
|
||||
t.add_column('RX')
|
||||
for name, value in stats['PluginManager'].items():
|
||||
t.add_row(
|
||||
name,
|
||||
str(value["enabled"]),
|
||||
value["version"],
|
||||
str(value["tx"]),
|
||||
str(value["rx"]),
|
||||
str(value['enabled']),
|
||||
value['version'],
|
||||
str(value['tx']),
|
||||
str(value['rx']),
|
||||
)
|
||||
|
||||
if "All" in show_section or "PluginManager" in show_section:
|
||||
if 'All' in show_section or 'PluginManager' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# Now show the client stats
|
||||
t = Table(title="Client Stats")
|
||||
t.add_column("Key")
|
||||
t.add_column("Value")
|
||||
for key, value in stats["APRSClientStats"].items():
|
||||
t = Table(title='Client Stats')
|
||||
t.add_column('Key')
|
||||
t.add_column('Value')
|
||||
for key, value in stats['APRSClientStats'].items():
|
||||
t.add_row(key, str(value))
|
||||
|
||||
if "All" in show_section or "APRSClientStats" in show_section:
|
||||
if 'All' in show_section or 'APRSClientStats' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# now show the packet list
|
||||
packet_list = stats.get("PacketList")
|
||||
t = Table(title="Packet List")
|
||||
t.add_column("Key")
|
||||
t.add_column("Value")
|
||||
t.add_row("Total Received", str(packet_list["rx"]))
|
||||
t.add_row("Total Sent", str(packet_list["tx"]))
|
||||
packet_list = stats.get('PacketList')
|
||||
t = Table(title='Packet List')
|
||||
t.add_column('Key')
|
||||
t.add_column('Value')
|
||||
t.add_row('Total Received', str(packet_list['rx']))
|
||||
t.add_row('Total Sent', str(packet_list['tx']))
|
||||
|
||||
if "All" in show_section or "PacketList" in show_section:
|
||||
if 'All' in show_section or 'PacketList' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# now show the seen list
|
||||
seen_list = stats.get("SeenList")
|
||||
seen_list = stats.get('SeenList')
|
||||
sorted_seen_list = sorted(
|
||||
seen_list.items(),
|
||||
)
|
||||
t = Table(title="Seen List")
|
||||
t.add_column("Callsign")
|
||||
t.add_column("Message Count")
|
||||
t.add_column("Last Heard")
|
||||
t = Table(title='Seen List')
|
||||
t.add_column('Callsign')
|
||||
t.add_column('Message Count')
|
||||
t.add_column('Last Heard')
|
||||
for key, value in sorted_seen_list:
|
||||
t.add_row(
|
||||
key,
|
||||
str(value["count"]),
|
||||
str(value["last"]),
|
||||
str(value['count']),
|
||||
str(value['last']),
|
||||
)
|
||||
|
||||
if "All" in show_section or "SeenList" in show_section:
|
||||
if 'All' in show_section or 'SeenList' in show_section:
|
||||
console.print(t)
|
||||
|
||||
# now show the watch list
|
||||
watch_list = stats.get("WatchList")
|
||||
watch_list = stats.get('WatchList')
|
||||
sorted_watch_list = sorted(
|
||||
watch_list.items(),
|
||||
)
|
||||
t = Table(title="Watch List")
|
||||
t.add_column("Callsign")
|
||||
t.add_column("Last Heard")
|
||||
t = Table(title='Watch List')
|
||||
t.add_column('Callsign')
|
||||
t.add_column('Last Heard')
|
||||
for key, value in sorted_watch_list:
|
||||
t.add_row(
|
||||
key,
|
||||
str(value["last"]),
|
||||
str(value['last']),
|
||||
)
|
||||
|
||||
if "All" in show_section or "WatchList" in show_section:
|
||||
if 'All' in show_section or 'WatchList' in show_section:
|
||||
console.print(t)
|
||||
|
@ -19,12 +19,12 @@ from aprsd import plugin as aprsd_plugin
|
||||
from aprsd.main import cli
|
||||
from aprsd.plugins import fortune, notify, ping, time, version, weather
|
||||
|
||||
LOG = logging.getLogger("APRSD")
|
||||
PYPI_URL = "https://pypi.org/search/"
|
||||
LOG = logging.getLogger('APRSD')
|
||||
PYPI_URL = 'https://pypi.org/search/'
|
||||
|
||||
|
||||
def onerror(name):
|
||||
print(f"Error importing module {name}")
|
||||
print(f'Error importing module {name}')
|
||||
type, value, traceback = sys.exc_info()
|
||||
print_tb(traceback)
|
||||
|
||||
@ -40,19 +40,19 @@ def is_plugin(obj):
|
||||
def plugin_type(obj):
|
||||
for c in inspect.getmro(obj):
|
||||
if issubclass(c, aprsd_plugin.APRSDRegexCommandPluginBase):
|
||||
return "RegexCommand"
|
||||
return 'RegexCommand'
|
||||
if issubclass(c, aprsd_plugin.APRSDWatchListPluginBase):
|
||||
return "WatchList"
|
||||
return 'WatchList'
|
||||
if issubclass(c, aprsd_plugin.APRSDPluginBase):
|
||||
return "APRSDPluginBase"
|
||||
return 'APRSDPluginBase'
|
||||
|
||||
return "Unknown"
|
||||
return 'Unknown'
|
||||
|
||||
|
||||
def walk_package(package):
|
||||
return pkgutil.walk_packages(
|
||||
package.__path__,
|
||||
package.__name__ + ".",
|
||||
package.__name__ + '.',
|
||||
onerror=onerror,
|
||||
)
|
||||
|
||||
@ -62,23 +62,23 @@ def get_module_info(package_name, module_name, module_path):
|
||||
return None
|
||||
|
||||
dir_path = os.path.realpath(module_path)
|
||||
pattern = "*.py"
|
||||
pattern = '*.py'
|
||||
|
||||
obj_list = []
|
||||
|
||||
for path, _subdirs, files in os.walk(dir_path):
|
||||
for name in files:
|
||||
if fnmatch.fnmatch(name, pattern):
|
||||
module = smuggle(f"{path}/{name}")
|
||||
module = smuggle(f'{path}/{name}')
|
||||
for mem_name, obj in inspect.getmembers(module):
|
||||
if inspect.isclass(obj) and is_plugin(obj):
|
||||
obj_list.append(
|
||||
{
|
||||
"package": package_name,
|
||||
"name": mem_name,
|
||||
"obj": obj,
|
||||
"version": obj.version,
|
||||
"path": f"{'.'.join([module_name, obj.__name__])}",
|
||||
'package': package_name,
|
||||
'name': mem_name,
|
||||
'obj': obj,
|
||||
'version': obj.version,
|
||||
'path': f'{".".join([module_name, obj.__name__])}',
|
||||
},
|
||||
)
|
||||
|
||||
@ -89,17 +89,17 @@ def _get_installed_aprsd_items():
|
||||
# installed plugins
|
||||
plugins = {}
|
||||
extensions = {}
|
||||
for finder, name, ispkg in pkgutil.iter_modules():
|
||||
if ispkg and name.startswith("aprsd_"):
|
||||
for _finder, name, ispkg in pkgutil.iter_modules():
|
||||
if ispkg and name.startswith('aprsd_'):
|
||||
module = importlib.import_module(name)
|
||||
pkgs = walk_package(module)
|
||||
for pkg in pkgs:
|
||||
pkg_info = get_module_info(
|
||||
module.__name__, pkg.name, module.__path__[0]
|
||||
)
|
||||
if "plugin" in name:
|
||||
if 'plugin' in name:
|
||||
plugins[name] = pkg_info
|
||||
elif "extension" in name:
|
||||
elif 'extension' in name:
|
||||
extensions[name] = pkg_info
|
||||
return plugins, extensions
|
||||
|
||||
@ -126,57 +126,57 @@ def show_built_in_plugins(console):
|
||||
cls = entry[1]
|
||||
if issubclass(cls, aprsd_plugin.APRSDPluginBase):
|
||||
info = {
|
||||
"name": cls.__qualname__,
|
||||
"path": f"{cls.__module__}.{cls.__qualname__}",
|
||||
"version": cls.version,
|
||||
"docstring": cls.__doc__,
|
||||
"short_desc": cls.short_description,
|
||||
'name': cls.__qualname__,
|
||||
'path': f'{cls.__module__}.{cls.__qualname__}',
|
||||
'version': cls.version,
|
||||
'docstring': cls.__doc__,
|
||||
'short_desc': cls.short_description,
|
||||
}
|
||||
|
||||
if issubclass(cls, aprsd_plugin.APRSDRegexCommandPluginBase):
|
||||
info["command_regex"] = cls.command_regex
|
||||
info["type"] = "RegexCommand"
|
||||
info['command_regex'] = cls.command_regex
|
||||
info['type'] = 'RegexCommand'
|
||||
|
||||
if issubclass(cls, aprsd_plugin.APRSDWatchListPluginBase):
|
||||
info["type"] = "WatchList"
|
||||
info['type'] = 'WatchList'
|
||||
|
||||
plugins.append(info)
|
||||
|
||||
plugins = sorted(plugins, key=lambda i: i["name"])
|
||||
plugins = sorted(plugins, key=lambda i: i['name'])
|
||||
|
||||
table = Table(
|
||||
title="[not italic]:snake:[/] [bold][magenta]APRSD Built-in Plugins [not italic]:snake:[/]",
|
||||
title='[not italic]:snake:[/] [bold][magenta]APRSD Built-in Plugins [not italic]:snake:[/]',
|
||||
)
|
||||
table.add_column("Plugin Name", style="cyan", no_wrap=True)
|
||||
table.add_column("Info", style="bold yellow")
|
||||
table.add_column("Type", style="bold green")
|
||||
table.add_column("Plugin Path", style="bold blue")
|
||||
table.add_column('Plugin Name', style='cyan', no_wrap=True)
|
||||
table.add_column('Info', style='bold yellow')
|
||||
table.add_column('Type', style='bold green')
|
||||
table.add_column('Plugin Path', style='bold blue')
|
||||
for entry in plugins:
|
||||
table.add_row(entry["name"], entry["short_desc"], entry["type"], entry["path"])
|
||||
table.add_row(entry['name'], entry['short_desc'], entry['type'], entry['path'])
|
||||
|
||||
console.print(table)
|
||||
|
||||
|
||||
def _get_pypi_packages():
|
||||
if simple_r := requests.get(
|
||||
"https://pypi.org/simple",
|
||||
headers={"Accept": "application/vnd.pypi.simple.v1+json"},
|
||||
'https://pypi.org/simple',
|
||||
headers={'Accept': 'application/vnd.pypi.simple.v1+json'},
|
||||
):
|
||||
simple_response = simple_r.json()
|
||||
else:
|
||||
simple_response = {}
|
||||
|
||||
key = "aprsd"
|
||||
key = 'aprsd'
|
||||
matches = [
|
||||
p["name"] for p in simple_response["projects"] if p["name"].startswith(key)
|
||||
p['name'] for p in simple_response['projects'] if p['name'].startswith(key)
|
||||
]
|
||||
|
||||
packages = []
|
||||
for pkg in matches:
|
||||
# Get info for first match
|
||||
if r := requests.get(
|
||||
f"https://pypi.org/pypi/{pkg}/json",
|
||||
headers={"Accept": "application/json"},
|
||||
f'https://pypi.org/pypi/{pkg}/json',
|
||||
headers={'Accept': 'application/json'},
|
||||
):
|
||||
packages.append(r.json())
|
||||
|
||||
@ -187,40 +187,40 @@ def show_pypi_plugins(installed_plugins, console):
|
||||
packages = _get_pypi_packages()
|
||||
|
||||
title = Text.assemble(
|
||||
("Pypi.org APRSD Installable Plugin Packages\n\n", "bold magenta"),
|
||||
("Install any of the following plugins with\n", "bold yellow"),
|
||||
("'pip install ", "bold white"),
|
||||
("<Plugin Package Name>'", "cyan"),
|
||||
('Pypi.org APRSD Installable Plugin Packages\n\n', 'bold magenta'),
|
||||
('Install any of the following plugins with\n', 'bold yellow'),
|
||||
("'pip install ", 'bold white'),
|
||||
("<Plugin Package Name>'", 'cyan'),
|
||||
)
|
||||
|
||||
table = Table(title=title)
|
||||
table.add_column("Plugin Package Name", style="cyan", no_wrap=True)
|
||||
table.add_column("Description", style="yellow")
|
||||
table.add_column("Version", style="yellow", justify="center")
|
||||
table.add_column("Released", style="bold green", justify="center")
|
||||
table.add_column("Installed?", style="red", justify="center")
|
||||
emoji = ":open_file_folder:"
|
||||
table.add_column('Plugin Package Name', style='cyan', no_wrap=True)
|
||||
table.add_column('Description', style='yellow')
|
||||
table.add_column('Version', style='yellow', justify='center')
|
||||
table.add_column('Released', style='bold green', justify='center')
|
||||
table.add_column('Installed?', style='red', justify='center')
|
||||
emoji = ':open_file_folder:'
|
||||
for package in packages:
|
||||
link = package["info"]["package_url"]
|
||||
version = package["info"]["version"]
|
||||
package_name = package["info"]["name"]
|
||||
description = package["info"]["summary"]
|
||||
created = package["releases"][version][0]["upload_time"]
|
||||
link = package['info']['package_url']
|
||||
version = package['info']['version']
|
||||
package_name = package['info']['name']
|
||||
description = package['info']['summary']
|
||||
created = package['releases'][version][0]['upload_time']
|
||||
|
||||
if "aprsd-" not in package_name or "-plugin" not in package_name:
|
||||
if 'aprsd-' not in package_name or '-plugin' not in package_name:
|
||||
continue
|
||||
|
||||
under = package_name.replace("-", "_")
|
||||
installed = "Yes" if under in installed_plugins else "No"
|
||||
under = package_name.replace('-', '_')
|
||||
installed = 'Yes' if under in installed_plugins else 'No'
|
||||
table.add_row(
|
||||
f"[link={link}]{emoji}[/link] {package_name}",
|
||||
f'[link={link}]{emoji}[/link] {package_name}',
|
||||
description,
|
||||
version,
|
||||
created,
|
||||
installed,
|
||||
)
|
||||
|
||||
console.print("\n")
|
||||
console.print('\n')
|
||||
console.print(table)
|
||||
|
||||
|
||||
@ -228,39 +228,39 @@ def show_pypi_extensions(installed_extensions, console):
|
||||
packages = _get_pypi_packages()
|
||||
|
||||
title = Text.assemble(
|
||||
("Pypi.org APRSD Installable Extension Packages\n\n", "bold magenta"),
|
||||
("Install any of the following extensions by running\n", "bold yellow"),
|
||||
("'pip install ", "bold white"),
|
||||
("<Plugin Package Name>'", "cyan"),
|
||||
('Pypi.org APRSD Installable Extension Packages\n\n', 'bold magenta'),
|
||||
('Install any of the following extensions by running\n', 'bold yellow'),
|
||||
("'pip install ", 'bold white'),
|
||||
("<Plugin Package Name>'", 'cyan'),
|
||||
)
|
||||
table = Table(title=title)
|
||||
table.add_column("Extension Package Name", style="cyan", no_wrap=True)
|
||||
table.add_column("Description", style="yellow")
|
||||
table.add_column("Version", style="yellow", justify="center")
|
||||
table.add_column("Released", style="bold green", justify="center")
|
||||
table.add_column("Installed?", style="red", justify="center")
|
||||
emoji = ":open_file_folder:"
|
||||
table.add_column('Extension Package Name', style='cyan', no_wrap=True)
|
||||
table.add_column('Description', style='yellow')
|
||||
table.add_column('Version', style='yellow', justify='center')
|
||||
table.add_column('Released', style='bold green', justify='center')
|
||||
table.add_column('Installed?', style='red', justify='center')
|
||||
emoji = ':open_file_folder:'
|
||||
|
||||
for package in packages:
|
||||
link = package["info"]["package_url"]
|
||||
version = package["info"]["version"]
|
||||
package_name = package["info"]["name"]
|
||||
description = package["info"]["summary"]
|
||||
created = package["releases"][version][0]["upload_time"]
|
||||
if "aprsd-" not in package_name or "-extension" not in package_name:
|
||||
link = package['info']['package_url']
|
||||
version = package['info']['version']
|
||||
package_name = package['info']['name']
|
||||
description = package['info']['summary']
|
||||
created = package['releases'][version][0]['upload_time']
|
||||
if 'aprsd-' not in package_name or '-extension' not in package_name:
|
||||
continue
|
||||
|
||||
under = package_name.replace("-", "_")
|
||||
installed = "Yes" if under in installed_extensions else "No"
|
||||
under = package_name.replace('-', '_')
|
||||
installed = 'Yes' if under in installed_extensions else 'No'
|
||||
table.add_row(
|
||||
f"[link={link}]{emoji}[/link] {package_name}",
|
||||
f'[link={link}]{emoji}[/link] {package_name}',
|
||||
description,
|
||||
version,
|
||||
created,
|
||||
installed,
|
||||
)
|
||||
|
||||
console.print("\n")
|
||||
console.print('\n')
|
||||
console.print(table)
|
||||
|
||||
|
||||
@ -269,24 +269,24 @@ def show_installed_plugins(installed_plugins, console):
|
||||
return
|
||||
|
||||
table = Table(
|
||||
title="[not italic]:snake:[/] [bold][magenta]APRSD Installed 3rd party Plugins [not italic]:snake:[/]",
|
||||
title='[not italic]:snake:[/] [bold][magenta]APRSD Installed 3rd party Plugins [not italic]:snake:[/]',
|
||||
)
|
||||
table.add_column("Package Name", style=" bold white", no_wrap=True)
|
||||
table.add_column("Plugin Name", style="cyan", no_wrap=True)
|
||||
table.add_column("Version", style="yellow", justify="center")
|
||||
table.add_column("Type", style="bold green")
|
||||
table.add_column("Plugin Path", style="bold blue")
|
||||
table.add_column('Package Name', style=' bold white', no_wrap=True)
|
||||
table.add_column('Plugin Name', style='cyan', no_wrap=True)
|
||||
table.add_column('Version', style='yellow', justify='center')
|
||||
table.add_column('Type', style='bold green')
|
||||
table.add_column('Plugin Path', style='bold blue')
|
||||
for name in installed_plugins:
|
||||
for plugin in installed_plugins[name]:
|
||||
table.add_row(
|
||||
name.replace("_", "-"),
|
||||
plugin["name"],
|
||||
plugin["version"],
|
||||
plugin_type(plugin["obj"]),
|
||||
plugin["path"],
|
||||
name.replace('_', '-'),
|
||||
plugin['name'],
|
||||
plugin['version'],
|
||||
plugin_type(plugin['obj']),
|
||||
plugin['path'],
|
||||
)
|
||||
|
||||
console.print("\n")
|
||||
console.print('\n')
|
||||
console.print(table)
|
||||
|
||||
|
||||
@ -298,14 +298,14 @@ def list_plugins(ctx):
|
||||
"""List the built in plugins available to APRSD."""
|
||||
console = Console()
|
||||
|
||||
with console.status("Show Built-in Plugins") as status:
|
||||
with console.status('Show Built-in Plugins') as status:
|
||||
show_built_in_plugins(console)
|
||||
|
||||
status.update("Fetching pypi.org plugins")
|
||||
status.update('Fetching pypi.org plugins')
|
||||
installed_plugins = get_installed_plugins()
|
||||
show_pypi_plugins(installed_plugins, console)
|
||||
|
||||
status.update("Looking for installed APRSD plugins")
|
||||
status.update('Looking for installed APRSD plugins')
|
||||
show_installed_plugins(installed_plugins, console)
|
||||
|
||||
|
||||
@ -317,9 +317,9 @@ def list_extensions(ctx):
|
||||
"""List the built in plugins available to APRSD."""
|
||||
console = Console()
|
||||
|
||||
with console.status("Show APRSD Extensions") as status:
|
||||
status.update("Fetching pypi.org APRSD Extensions")
|
||||
with console.status('Show APRSD Extensions') as status:
|
||||
status.update('Fetching pypi.org APRSD Extensions')
|
||||
|
||||
status.update("Looking for installed APRSD Extensions")
|
||||
status.update('Looking for installed APRSD Extensions')
|
||||
installed_extensions = get_installed_extensions()
|
||||
show_pypi_extensions(installed_extensions, console)
|
||||
|
@ -173,3 +173,20 @@ skip_gitignore = true
|
||||
branch = true
|
||||
|
||||
[tool.setuptools_scm]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 88
|
||||
select = [
|
||||
"F", # pyflakes rules
|
||||
"E", # pycodestyle error rules
|
||||
"W", # pycodestyle warning rules
|
||||
"B", # flake8-bugbear rules
|
||||
# "I", # isort rules
|
||||
]
|
||||
ignore = [
|
||||
"E501", # line-too-long
|
||||
]
|
||||
|
||||
[tool.ruff.format]
|
||||
indent-style = "space"
|
||||
quote-style = "single"
|
||||
|
Loading…
Reference in New Issue
Block a user