mirror of https://github.com/craigerl/aprsd.git
Added new list-plugins command
This patch adds the new list-plugins command that shows the list of built in plugins for APRSD.
This commit is contained in:
parent
a8a6b1aa07
commit
446484e631
|
@ -67,7 +67,8 @@ def main():
|
||||||
# First import all the possible commands for the CLI
|
# First import all the possible commands for the CLI
|
||||||
# The commands themselves live in the cmds directory
|
# The commands themselves live in the cmds directory
|
||||||
from .cmds import ( # noqa
|
from .cmds import ( # noqa
|
||||||
completion, dev, healthcheck, listen, send_message, server,
|
completion, dev, healthcheck, list_plugins, listen, send_message,
|
||||||
|
server,
|
||||||
)
|
)
|
||||||
cli()
|
cli()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import inspect
|
||||||
|
import logging
|
||||||
|
from textwrap import indent
|
||||||
|
|
||||||
|
import click
|
||||||
|
from tabulate import tabulate
|
||||||
|
|
||||||
|
from aprsd import cli_helper, plugin
|
||||||
|
from aprsd.plugins import (
|
||||||
|
email, fortune, location, notify, ping, query, time, version, weather,
|
||||||
|
)
|
||||||
|
|
||||||
|
from ..aprsd import cli
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger("APRSD")
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@cli_helper.add_options(cli_helper.common_options)
|
||||||
|
@click.pass_context
|
||||||
|
@cli_helper.process_standard_options_no_config
|
||||||
|
def list_plugins(ctx):
|
||||||
|
"""List the built in plugins available to APRSD."""
|
||||||
|
|
||||||
|
modules = [email, fortune, location, notify, ping, query, time, version, weather]
|
||||||
|
plugins = []
|
||||||
|
|
||||||
|
for module in modules:
|
||||||
|
entries = inspect.getmembers(module, inspect.isclass)
|
||||||
|
for entry in entries:
|
||||||
|
cls = entry[1]
|
||||||
|
if issubclass(cls, plugin.APRSDPluginBase):
|
||||||
|
info = {
|
||||||
|
"name": cls.__qualname__,
|
||||||
|
"path": f"{cls.__module__}.{cls.__qualname__}",
|
||||||
|
"version": cls.version,
|
||||||
|
"docstring": cls.__doc__,
|
||||||
|
"short_desc": cls.short_description,
|
||||||
|
}
|
||||||
|
|
||||||
|
if issubclass(cls, plugin.APRSDRegexCommandPluginBase):
|
||||||
|
info["command_regex"] = cls.command_regex
|
||||||
|
info["type"] = "RegexCommand"
|
||||||
|
|
||||||
|
if issubclass(cls, plugin.APRSDWatchListPluginBase):
|
||||||
|
info["type"] = "WatchList"
|
||||||
|
|
||||||
|
plugins.append(info)
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
headers = ("Plugin Name", "Plugin Path", "Type", "Info")
|
||||||
|
|
||||||
|
for entry in plugins:
|
||||||
|
lines.append(
|
||||||
|
(entry["name"], entry["path"], entry["type"], entry["short_desc"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
click.echo(indent(tabulate(lines, headers, disable_numparse=True), " "))
|
|
@ -12,6 +12,7 @@ import threading
|
||||||
import pluggy
|
import pluggy
|
||||||
from thesmuggler import smuggle
|
from thesmuggler import smuggle
|
||||||
|
|
||||||
|
import aprsd
|
||||||
from aprsd import client, messaging, packets, threads
|
from aprsd import client, messaging, packets, threads
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ class APRSDPluginBase(metaclass=abc.ABCMeta):
|
||||||
config = None
|
config = None
|
||||||
rx_count = 0
|
rx_count = 0
|
||||||
tx_count = 0
|
tx_count = 0
|
||||||
version = "1.0"
|
version = aprsd.__version__
|
||||||
|
|
||||||
# Holds the list of APRSDThreads that the plugin creates
|
# Holds the list of APRSDThreads that the plugin creates
|
||||||
threads = []
|
threads = []
|
||||||
|
|
|
@ -59,9 +59,9 @@ class EmailInfo:
|
||||||
class EmailPlugin(plugin.APRSDRegexCommandPluginBase):
|
class EmailPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Email Plugin."""
|
"""Email Plugin."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^-.*"
|
command_regex = "^-.*"
|
||||||
command_name = "email"
|
command_name = "email"
|
||||||
|
short_description = "Send and Receive email"
|
||||||
|
|
||||||
# message_number:time combos so we don't resend the same email in
|
# message_number:time combos so we don't resend the same email in
|
||||||
# five mins {int:int}
|
# five mins {int:int}
|
||||||
|
|
|
@ -11,9 +11,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
|
class FortunePlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Fortune."""
|
"""Fortune."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[fF]"
|
command_regex = "^[fF]"
|
||||||
command_name = "fortune"
|
command_name = "fortune"
|
||||||
|
short_description = "Give me a fortune"
|
||||||
|
|
||||||
fortune_path = None
|
fortune_path = None
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class LocationPlugin(plugin.APRSDRegexCommandPluginBase, plugin.APRSFIKEYMixin):
|
class LocationPlugin(plugin.APRSDRegexCommandPluginBase, plugin.APRSFIKEYMixin):
|
||||||
"""Location!"""
|
"""Location!"""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[lL]"
|
command_regex = "^[lL]"
|
||||||
command_name = "location"
|
command_name = "location"
|
||||||
|
short_description = "Where in the world is a CALLSIGN's last GPS beacon?"
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.ensure_aprs_fi_key()
|
self.ensure_aprs_fi_key()
|
||||||
|
|
|
@ -15,7 +15,7 @@ class NotifySeenPlugin(plugin.APRSDWatchListPluginBase):
|
||||||
seen was older than the configured age limit.
|
seen was older than the configured age limit.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version = "1.0"
|
short_description = "Notify me when a CALLSIGN is recently seen on APRS-IS"
|
||||||
|
|
||||||
def process(self, packet):
|
def process(self, packet):
|
||||||
LOG.info("NotifySeenPlugin")
|
LOG.info("NotifySeenPlugin")
|
||||||
|
|
|
@ -10,9 +10,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class PingPlugin(plugin.APRSDRegexCommandPluginBase):
|
class PingPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Ping."""
|
"""Ping."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[pP]"
|
command_regex = "^[pP]"
|
||||||
command_name = "ping"
|
command_name = "ping"
|
||||||
|
short_description = "reply with a Pong!"
|
||||||
|
|
||||||
@trace.trace
|
@trace.trace
|
||||||
def process(self, packet):
|
def process(self, packet):
|
||||||
|
|
|
@ -11,9 +11,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class QueryPlugin(plugin.APRSDRegexCommandPluginBase):
|
class QueryPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Query command."""
|
"""Query command."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = r"^\!.*"
|
command_regex = r"^\!.*"
|
||||||
command_name = "query"
|
command_name = "query"
|
||||||
|
short_description = "APRSD Owner command to query messages in the MsgTrack"
|
||||||
|
|
||||||
@trace.trace
|
@trace.trace
|
||||||
def process(self, packet):
|
def process(self, packet):
|
||||||
|
|
|
@ -14,9 +14,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class TimePlugin(plugin.APRSDRegexCommandPluginBase):
|
class TimePlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Time command."""
|
"""Time command."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[tT]"
|
command_regex = "^[tT]"
|
||||||
command_name = "time"
|
command_name = "time"
|
||||||
|
short_description = "What is the current local time."
|
||||||
|
|
||||||
def _get_local_tz(self):
|
def _get_local_tz(self):
|
||||||
return pytz.timezone(time.strftime("%Z"))
|
return pytz.timezone(time.strftime("%Z"))
|
||||||
|
@ -52,9 +52,9 @@ class TimePlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
class TimeOpenCageDataPlugin(TimePlugin, plugin.APRSFIKEYMixin):
|
class TimeOpenCageDataPlugin(TimePlugin, plugin.APRSFIKEYMixin):
|
||||||
"""geocage based timezone fetching."""
|
"""geocage based timezone fetching."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[tT]"
|
command_regex = "^[tT]"
|
||||||
command_name = "time"
|
command_name = "time"
|
||||||
|
short_description = "Current time of GPS beacon timezone. Uses OpenCage"
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.ensure_aprs_fi_key()
|
self.ensure_aprs_fi_key()
|
||||||
|
@ -114,9 +114,9 @@ class TimeOpenCageDataPlugin(TimePlugin, plugin.APRSFIKEYMixin):
|
||||||
class TimeOWMPlugin(TimePlugin, plugin.APRSFIKEYMixin):
|
class TimeOWMPlugin(TimePlugin, plugin.APRSFIKEYMixin):
|
||||||
"""OpenWeatherMap based timezone fetching."""
|
"""OpenWeatherMap based timezone fetching."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[tT]"
|
command_regex = "^[tT]"
|
||||||
command_name = "time"
|
command_name = "time"
|
||||||
|
short_description = "Current time of GPS beacon's timezone. Uses OpenWeatherMap"
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.ensure_aprs_fi_key()
|
self.ensure_aprs_fi_key()
|
||||||
|
|
|
@ -10,9 +10,9 @@ LOG = logging.getLogger("APRSD")
|
||||||
class VersionPlugin(plugin.APRSDRegexCommandPluginBase):
|
class VersionPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"""Version of APRSD Plugin."""
|
"""Version of APRSD Plugin."""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[vV]"
|
command_regex = "^[vV]"
|
||||||
command_name = "version"
|
command_name = "version"
|
||||||
|
short_description = "What is the APRSD Version"
|
||||||
|
|
||||||
# message_number:time combos so we don't resend the same email in
|
# message_number:time combos so we don't resend the same email in
|
||||||
# five mins {int:int}
|
# five mins {int:int}
|
||||||
|
|
|
@ -23,9 +23,9 @@ class USWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
"weather" - returns weather near the calling callsign
|
"weather" - returns weather near the calling callsign
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[wW]"
|
command_regex = "^[wW]"
|
||||||
command_name = "USWeather"
|
command_name = "USWeather"
|
||||||
|
short_description = "Provide USA only weather of GPS Beacon location"
|
||||||
|
|
||||||
@trace.trace
|
@trace.trace
|
||||||
def process(self, packet):
|
def process(self, packet):
|
||||||
|
@ -86,9 +86,9 @@ class USMetarPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[metar]"
|
command_regex = "^[metar]"
|
||||||
command_name = "USMetar"
|
command_name = "USMetar"
|
||||||
|
short_description = "USA only METAR of GPS Beacon location"
|
||||||
|
|
||||||
@trace.trace
|
@trace.trace
|
||||||
def process(self, packet):
|
def process(self, packet):
|
||||||
|
@ -178,9 +178,9 @@ class OWMWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[wW]"
|
command_regex = "^[wW]"
|
||||||
command_name = "OpenWeatherMap"
|
command_name = "OpenWeatherMap"
|
||||||
|
short_description = "OpenWeatherMap weather of GPS Beacon location"
|
||||||
|
|
||||||
def help(self):
|
def help(self):
|
||||||
_help = [
|
_help = [
|
||||||
|
@ -308,9 +308,9 @@ class AVWXWeatherPlugin(plugin.APRSDRegexCommandPluginBase):
|
||||||
docker build -f Dockerfile -t avwx-api:master .
|
docker build -f Dockerfile -t avwx-api:master .
|
||||||
"""
|
"""
|
||||||
|
|
||||||
version = "1.0"
|
|
||||||
command_regex = "^[mM]"
|
command_regex = "^[mM]"
|
||||||
command_name = "AVWXWeather"
|
command_name = "AVWXWeather"
|
||||||
|
short_description = "AVWX weather of GPS Beacon location"
|
||||||
|
|
||||||
def help(self):
|
def help(self):
|
||||||
_help = [
|
_help = [
|
||||||
|
|
|
@ -20,3 +20,4 @@ thesmuggler
|
||||||
update_checker
|
update_checker
|
||||||
flask-socketio
|
flask-socketio
|
||||||
eventlet
|
eventlet
|
||||||
|
tabulate
|
||||||
|
|
|
@ -104,6 +104,8 @@ six==1.16.0
|
||||||
# imapclient
|
# imapclient
|
||||||
# pyopenssl
|
# pyopenssl
|
||||||
# signalslot
|
# signalslot
|
||||||
|
tabulate==0.8.9
|
||||||
|
# via -r requirements.in
|
||||||
thesmuggler==1.0.1
|
thesmuggler==1.0.1
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
update-checker==0.18.0
|
update-checker==0.18.0
|
||||||
|
|
Loading…
Reference in New Issue