Compare commits

...

10 Commits

Author SHA1 Message Date
Hemna 849639767d force requirements.txt 2023-07-12 13:44:11 -04:00
Hemna 931771fc7b generic aprsd 2023-07-10 14:26:00 -04:00
Hemna 62e3532dd2 >=3.0.0 2023-07-10 13:08:19 -04:00
Hemna bc3595d7a2 update 2023-01-10 14:19:20 -05:00
Hemna e74585f4e7 Update for aprsd 3.0.0
This patch adds the new conf settings for slack plugin
2023-01-10 14:10:46 -05:00
Hemna 8367cc8fd2 Updated regex for message plugin
This regex will match on
s
s foo
slack foo
2022-12-29 14:41:39 -05:00
Hemna 7c28bb9886 Removed import of aprsd.messaging 2022-12-29 12:14:20 -05:00
Hemna 3bfc0188c0 Fixed missing import for config 2022-12-29 10:58:22 -05:00
Hemna 63726e426e Update for APRSD 3.0.0 release.
This provides the new config options defined in the plugin code
itself.
2022-12-29 09:23:32 -05:00
Hemna b624055d06 Update for aprsd >= 2.7.0
the new aprsd changes the packets to a dataclass object, so access
to the attributes is different.
2022-12-20 17:12:20 -05:00
14 changed files with 287 additions and 239 deletions

View File

@ -1,9 +1,25 @@
CHANGES
=======
v1.2.0
------
* update
* Update for aprsd 3.0.0
v1.1.0
------
* Updated regex for message plugin
* Removed import of aprsd.messaging
* Fixed missing import for config
* Update for APRSD 3.0.0 release
* Update for aprsd >= 2.7.0
v1.0.5
------
* 1.0.5
* cleanup
* fix tox runs
* More cleanup

View File

@ -1,9 +1,12 @@
import logging
from oslo_config import cfg
from slack_sdk import WebClient
import aprsd_slack_plugin
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
@ -39,33 +42,29 @@ class SlackPluginBase:
"""
version = aprsd_slack_plugin.__version__
swc = None
slack_channels = None
def setup_slack(self):
"""Create the slack require client from config."""
# signing_secret = self.config["slack"]["signing_secret"]
try:
self.config.exists(["services", "slack", "bot_token"])
except Exception as ex:
LOG.error("Failed to find config slack:bot_token {}".format(ex))
return "No slack bot_token found"
if not CONF.aprsd_slack_plugin.signing_secret:
LOG.error("Failed to find config aprsd_slack_plugin.signing_secret")
return "No slack signing_secret found"
bot_token = self.config["services"]["slack"]["bot_token"]
if not bot_token:
if not CONF.aprsd_slack_plugin.bot_token:
LOG.error(
"APRSD config is missing slack: bot_token:<token>. "
"APRSD config is missing aprsd_slack_plugin.bot_token. "
"Please install the slack app and get the "
"Bot User OAth Access Token.",
)
return False
self.swc = WebClient(token=bot_token)
self.slack_channels = self.config["services"]["slack"].get("channels", None)
if not self.slack_channels:
LOG.error(
"APRSD config is missing slack: channels: <name> "
"Please add a slack channel name to send messages.",
)
if not CONF.aprsd_slack_plugin.channels:
LOG.error("aprsd_slack_plugin.channels is missing")
return False
self.swc = WebClient(token=CONF.aprsd_slack_plugin.bot_token)
self.slack_channels = CONF.aprsd_slack_plugin.channels
return True

View File

@ -0,0 +1,7 @@
from oslo_config import cfg
from aprsd_slack_plugin.conf import slack
CONF = cfg.CONF
slack.register_opts(CONF)

View File

@ -0,0 +1,81 @@
# Copyright 2015 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
This is the single point of entry to generate the sample configuration
file for Nova. It collects all the necessary info from the other modules
in this package. It is assumed that:
* every other module in this package has a 'list_opts' function which
return a dict where
* the keys are strings which are the group names
* the value of each key is a list of config options for that group
* the nova.conf package doesn't have further packages with config options
* this module is only used in the context of sample file generation
"""
import collections
import importlib
import os
import pkgutil
LIST_OPTS_FUNC_NAME = "list_opts"
def _tupleize(dct):
"""Take the dict of options and convert to the 2-tuple format."""
return [(key, val) for key, val in dct.items()]
def list_opts():
opts = collections.defaultdict(list)
module_names = _list_module_names()
imported_modules = _import_modules(module_names)
_append_config_options(imported_modules, opts)
return _tupleize(opts)
def _list_module_names():
module_names = []
package_path = os.path.dirname(os.path.abspath(__file__))
for _, modname, ispkg in pkgutil.iter_modules(path=[package_path]):
if modname == "opts" or ispkg:
continue
else:
module_names.append(modname)
return module_names
def _import_modules(module_names):
imported_modules = []
for modname in module_names:
mod = importlib.import_module("aprsd_slack_plugin.conf." + modname)
if not hasattr(mod, LIST_OPTS_FUNC_NAME):
msg = (
"The module 'aprsd_slack_plugin.conf.%s' should have a '%s' "
"function which returns the config options." % (modname, LIST_OPTS_FUNC_NAME)
)
raise Exception(msg)
else:
imported_modules.append(mod)
return imported_modules
def _append_config_options(imported_modules, config_options):
for mod in imported_modules:
configs = mod.list_opts()
for key, val in configs.items():
config_options[key].extend(val)

View File

@ -0,0 +1,41 @@
from oslo_config import cfg
slack_group = cfg.OptGroup(
name="aprsd_slack_plugin",
title="APRSD Slack Plugin settings",
)
slack_opts = [
cfg.StrOpt(
"signing_secret",
default=None,
help="Your Slack account signing secret"
"You have to create a slack bot account first. "
"https://api.slack.com/start/building/bolt-python",
),
cfg.StrOpt(
"bot_token",
default=None,
help="Your Slack bot's token",
),
cfg.ListOpt(
"channels",
default=None,
help="The channels you want messages sent to. This is a CSV list"
"of slack channel names.",
),
]
ALL_OPTS = slack_opts
def register_opts(cfg):
cfg.register_group(slack_group)
cfg.register_opts(ALL_OPTS, group=slack_group)
def list_opts():
return {
slack_group.name: slack_opts,
}

View File

@ -2,15 +2,23 @@ import logging
import re
import time
from aprsd import messaging, plugin, plugin_utils
from aprsd import packets, plugin, plugin_utils
from oslo_config import cfg
import aprsd_slack_plugin
from aprsd_slack_plugin import base_plugin
from aprsd_slack_plugin import conf # noqa
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandPluginBase):
class SlackLocationPlugin(
base_plugin.SlackPluginBase,
plugin.APRSDRegexCommandPluginBase,
plugin.APRSFIKEYMixin,
):
"""SlackCommandPlugin.
This APRSD plugin looks for the location command comming in
@ -34,7 +42,7 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
Install the app/bot into your workspace.
Edit your ~/.config/aprsd/aprsd.yml and add the section
Edit your ~/.config/aprsd/aprsd.conf and add the section
slack:
signing_secret: <signing secret token here>
bot_token: <Bot User OAuth Access Token here>
@ -47,24 +55,21 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
command_regex = "^[lL]"
command_name = "location-slack"
def setup(self):
self.ensure_aprs_fi_key()
if self.enabled:
config_set = self.setup_slack()
if not config_set:
self.enabled = False
def process(self, packet):
LOG.info("SlackCommandPlugin")
fromcall = packet["from"]
message = packet["message_text"]
is_setup = self.setup_slack()
if not is_setup:
return
fromcall = packet.from_call
message = packet.message_text
# get last location of a callsign, get descriptive name from weather service
try:
self.config.exists(["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
api_key = CONF.aprs_fi.apiKey
# optional second argument is a callsign to search
a = re.search(r"^.*\s+(.*)", message)
@ -78,10 +83,10 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi '{}'".format(ex))
LOG.error(f"Failed to fetch aprs.fi '{ex}'")
return "Failed to fetch aprs.fi location"
LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
LOG.debug(f"LocationPlugin: aprs_data = {aprs_data}")
if not len(aprs_data["entries"]):
LOG.error("Didn't get any entries from aprs.fi")
return "Failed to fetch aprs.fi location"
@ -103,7 +108,7 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
except Exception:
LOG.warning("Couldn't fetch forecast.weather.gov")
callsign_url = "<http://aprs.fi/info/a/{}|{}>".format(searchcall, searchcall)
callsign_url = f"<http://aprs.fi/info/a/{searchcall}|{searchcall}>"
aprs_url = "<http://aprs.fi/#!mt=roadmap&z=15&lat={}&lng={}|" " http://aprs.fi/>".format(
lat,
@ -114,7 +119,7 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
message["username"] = "APRSD - Slack Location Plugin"
message["icon_emoji"] = ":satellite_antenna:"
message["attachments"] = [{}]
message["text"] = "{} - Location".format(callsign_url)
message["text"] = f"{callsign_url} - Location"
message["channel"] = "#random"
attachment = message["attachments"][0]
@ -140,15 +145,15 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
"title": "Altitude",
"value": altfeet,
"short": True,
"fallback": "Altitude - {}".format(altfeet),
"fallback": f"Altitude - {altfeet}",
},
)
attachment["fields"].append(
{
"title": "Time",
"value": "{} h ago".format(round(delta_hours, 1)),
"value": f"{round(delta_hours, 1)} h ago",
"short": True,
"fallback": "Time {} h ago".format(round(delta_hours, 1)),
"fallback": f"Time {round(delta_hours, 1)} h ago",
},
)
@ -160,4 +165,4 @@ class SlackLocationPlugin(base_plugin.SlackPluginBase, plugin.APRSDRegexCommandP
self.swc.chat_postMessage(**message)
# Don't have aprsd try and send a reply
return messaging.NULL_MESSAGE
return packets.NULL_MESSAGE

View File

@ -1,11 +1,15 @@
import logging
import re
from aprsd import messaging
from aprsd import packets
from oslo_config import cfg
import aprsd_slack_plugin
from aprsd_slack_plugin import base_plugin
from aprsd_slack_plugin import conf # noqa
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
@ -42,22 +46,23 @@ class SlackMessagePlugin(base_plugin.SlackPluginBase):
version = aprsd_slack_plugin.__version__
# matches any string starting with h or H
command_regex = "^[sS]"
command_regex = r"^([s]|[s]\s|slack)"
command_name = "message-slack"
def command(self, packet):
message = packet.get("message_text", None)
fromcall = packet.get("from", None)
LOG.info("SlackMessagePlugin '{}'".format(message))
def setup(self):
config_set = self.setup_slack()
if not config_set:
self.enabled = False
else:
self.enabled = True
is_setup = self.setup_slack()
if not is_setup:
LOG.error("Slack isn't setup!")
return
def command(self, packet):
message = packet.message_text
fromcall = packet.from_call
LOG.info(f"SlackMessagePlugin '{message}'")
# optional second argument is a callsign to search
a = re.search(r"^.*\s+(.*)", message)
LOG.debug(a)
if a is not None:
searchcall = a.group(1)
searchcall = searchcall.upper()
@ -68,7 +73,7 @@ class SlackMessagePlugin(base_plugin.SlackPluginBase):
slack_message = {}
slack_message["username"] = "APRSD - Slack Message Plugin"
slack_message["icon_emoji"] = ":satellite_antenna:"
slack_message["text"] = "{} says {}".format(fromcall, message)
slack_message["text"] = f"{fromcall} says {message}"
slack_message["channel"] = "#random"
LOG.debug(slack_message)
@ -79,4 +84,4 @@ class SlackMessagePlugin(base_plugin.SlackPluginBase):
# self.swc.chat_postMessage(**message)
# Don't have aprsd try and send a reply
return messaging.NULL_MESSAGE
return packets.NULL_MESSAGE

View File

@ -1,10 +1,14 @@
import logging
from aprsd import messaging, packets, plugin
from aprsd import packets, plugin
from oslo_config import cfg
import aprsd_slack_plugin
from aprsd_slack_plugin import base_plugin
from aprsd_slack_plugin import conf # noqa
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
@ -16,26 +20,29 @@ class SlackNotifyPlugin(
version = aprsd_slack_plugin.__version__
def setup(self):
config_set = self.setup_slack()
if not config_set:
self.enabled = False
else:
self.enabled = True
def process(self, packet):
LOG.info("SlackCommandPlugin")
fromcall = packet["from"]
fromcall = packet.from_call
# message = packet["message_text"]
is_setup = self.setup_slack()
if not is_setup:
return
wl = packets.WatchList()
if wl.is_old(packet["from"]):
if wl.is_old(fromcall):
# get last location of a callsign, get descriptive name from weather service
callsign_url = "<http://aprs.fi/info/a/{}|{}>".format(fromcall, fromcall)
callsign_url = f"<http://aprs.fi/info/a/{fromcall}|{fromcall}>"
message = {}
message["username"] = "APRSD - Slack Notification Plugin"
message["icon_emoji"] = ":satellite_antenna:"
message["attachments"] = [{}]
message["text"] = "{} - Is now on APRS".format(callsign_url)
message["text"] = f"{callsign_url} - Is now on APRS"
message["channel"] = "#hemna"
LOG.debug(message)
@ -46,4 +53,4 @@ class SlackNotifyPlugin(
self.swc.chat_postMessage(**message)
# Don't have aprsd try and send a reply
return messaging.NULL_MESSAGE
return packets.NULL_MESSAGE

View File

@ -4,107 +4,72 @@
#
# pip-compile --annotation-style=line --resolver=backtracking requirements-dev.in
#
alabaster==0.7.12 # via sphinx
aprsd==2.6.1 # via -r requirements-dev.in
aprslib==0.7.2 # via aprsd
attrs==22.1.0 # via aprsd, ax253, kiss3, pytest
ax253==0.1.5.post1 # via aprsd, kiss3
babel==2.11.0 # via sphinx
beautifulsoup4==4.11.1 # via aprsd
bidict==0.22.0 # via aprsd, python-socketio
bitarray==2.6.0 # via aprsd, ax253, kiss3
black==22.12.0 # via -r requirements-dev.in
build==0.9.0 # via pip-tools
cachetools==5.2.0 # via tox
certifi==2022.12.7 # via aprsd, requests
cffi==1.15.1 # via aprsd, cryptography
alabaster==0.7.13 # via sphinx
aprsd==1.0.0 # via -r requirements-dev.in
babel==2.12.1 # via sphinx
black==23.3.0 # via -r requirements-dev.in
build==0.10.0 # via pip-tools
cachetools==5.3.1 # via tox
certifi==2023.5.7 # via requests
cfgv==3.3.1 # via pre-commit
chardet==5.1.0 # via tox
charset-normalizer==2.1.1 # via aprsd, requests
click==8.1.3 # via aprsd, black, click-completion, flask, pip-tools
charset-normalizer==3.2.0 # via requests
click==8.1.4 # via aprsd, black, click-completion, pip-tools
click-completion==0.5.2 # via aprsd
colorama==0.4.6 # via tox
commonmark==0.9.1 # via aprsd, rich
coverage[toml]==6.5.0 # via pytest-cov
cryptography==38.0.4 # via aprsd, pyopenssl
coverage[toml]==7.2.7 # via pytest-cov
distlib==0.3.6 # via virtualenv
dnspython==2.2.1 # via aprsd, eventlet
docutils==0.19 # via sphinx
eventlet==0.33.2 # via aprsd
exceptiongroup==1.0.4 # via pytest
filelock==3.8.2 # via tox, virtualenv
docutils==0.20.1 # via sphinx
exceptiongroup==1.1.2 # via pytest
filelock==3.12.2 # via tox, virtualenv
flake8==6.0.0 # via -r requirements-dev.in, pep8-naming
flask==2.1.2 # via aprsd, flask-classful, flask-httpauth, flask-socketio
flask-classful==0.14.2 # via aprsd
flask-httpauth==4.7.0 # via aprsd
flask-socketio==5.3.2 # via aprsd
greenlet==2.0.1 # via aprsd, eventlet
identify==2.5.10 # via pre-commit
idna==3.4 # via aprsd, requests
identify==2.5.24 # via pre-commit
idna==3.4 # via requests
imagesize==1.4.1 # via sphinx
imapclient==2.3.1 # via aprsd
importlib-metadata==5.1.0 # via aprsd, ax253, flask, kiss3, sphinx
iniconfig==1.1.1 # via pytest
isort==5.11.3 # via -r requirements-dev.in
itsdangerous==2.1.2 # via aprsd, flask
jinja2==3.1.2 # via aprsd, click-completion, flask, sphinx
kiss3==8.0.0 # via aprsd
markupsafe==2.1.1 # via aprsd, jinja2
importlib-metadata==6.8.0 # via sphinx
iniconfig==2.0.0 # via pytest
isort==5.12.0 # via -r requirements-dev.in
jinja2==3.1.2 # via click-completion, sphinx
markupsafe==2.1.3 # via jinja2
mccabe==0.7.0 # via flake8
mypy==0.991 # via -r requirements-dev.in
mypy-extensions==0.4.3 # via black, mypy
nodeenv==1.7.0 # via pre-commit
packaging==22.0 # via build, pyproject-api, pytest, sphinx, tox
pathspec==0.10.3 # via black
pbr==5.11.0 # via -r requirements-dev.in, aprsd
pep517==0.13.0 # via build
pep8-naming==0.13.2 # via -r requirements-dev.in
pip-tools==6.12.1 # via -r requirements-dev.in
platformdirs==2.6.0 # via black, tox, virtualenv
pluggy==1.0.0 # via aprsd, pytest, tox
pre-commit==2.20.0 # via -r requirements-dev.in
mypy==1.4.1 # via -r requirements-dev.in
mypy-extensions==1.0.0 # via black, mypy
nodeenv==1.8.0 # via pre-commit
packaging==23.1 # via black, build, pyproject-api, pytest, sphinx, tox
pathspec==0.11.1 # via black
pbr==5.11.1 # via -r requirements-dev.in, aprsd
pep8-naming==0.13.3 # via -r requirements-dev.in
pip-tools==6.14.0 # via -r requirements-dev.in
platformdirs==3.8.1 # via black, tox, virtualenv
pluggy==1.2.0 # via aprsd, pytest, tox
pre-commit==3.3.3 # via -r requirements-dev.in
pycodestyle==2.10.0 # via flake8
pycparser==2.21 # via aprsd, cffi
pyflakes==3.0.1 # via flake8
pygments==2.13.0 # via aprsd, rich, sphinx
pyopenssl==22.1.0 # via aprsd
pyproject-api==1.2.1 # via tox
pyserial==3.5 # via aprsd, pyserial-asyncio
pyserial-asyncio==0.6 # via aprsd, kiss3
pytest==7.2.0 # via -r requirements-dev.in, pytest-cov
pytest-cov==4.0.0 # via -r requirements-dev.in
python-engineio==4.3.4 # via aprsd, python-socketio
python-socketio==5.7.2 # via aprsd, flask-socketio
pytz==2022.6 # via aprsd, babel
pygments==2.15.1 # via sphinx
pyproject-api==1.5.3 # via tox
pyproject-hooks==1.0.0 # via build
pytest==7.4.0 # via -r requirements-dev.in, pytest-cov
pytest-cov==4.1.0 # via -r requirements-dev.in
pyyaml==6.0 # via aprsd, pre-commit
requests==2.28.1 # via aprsd, sphinx, update-checker
rich==12.6.0 # via aprsd
shellingham==1.5.0 # via aprsd, click-completion
six==1.16.0 # via aprsd, click-completion, eventlet, imapclient
requests==2.31.0 # via aprsd, sphinx
shellingham==1.5.0.post1 # via click-completion
six==1.16.0 # via aprsd, click-completion, imapclient
snowballstemmer==2.2.0 # via sphinx
soupsieve==2.3.2.post1 # via aprsd, beautifulsoup4
sphinx==5.3.0 # via -r requirements-dev.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinx==7.0.1 # via -r requirements-dev.in
sphinxcontrib-applehelp==1.0.4 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==2.0.0 # via sphinx
sphinxcontrib-htmlhelp==2.0.1 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.5 # via sphinx
tabulate==0.9.0 # via aprsd
thesmuggler==1.0.1 # via aprsd
toml==0.10.2 # via pre-commit
tomli==2.0.1 # via black, build, coverage, mypy, pep517, pyproject-api, pytest, tox
tox==4.0.14 # via -r requirements-dev.in
typing-extensions==4.4.0 # via black, mypy
ua-parser==0.16.1 # via aprsd, user-agents
update-checker==0.18.0 # via aprsd
urllib3==1.26.13 # via aprsd, requests
user-agents==2.2.0 # via aprsd
virtualenv==20.17.1 # via pre-commit, tox
werkzeug==2.1.2 # via aprsd, flask
wheel==0.38.4 # via pip-tools
wrapt==1.14.1 # via aprsd
zipp==3.11.0 # via aprsd, importlib-metadata
tomli==2.0.1 # via black, build, coverage, mypy, pip-tools, pyproject-api, pyproject-hooks, pytest, tox
tox==4.6.4 # via -r requirements-dev.in
typing-extensions==4.7.1 # via black, mypy
urllib3==2.0.3 # via requests
virtualenv==20.23.1 # via pre-commit, tox
wheel==0.40.0 # via pip-tools
zipp==3.16.0 # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
# pip

View File

@ -1,4 +0,0 @@
pbr
slack_sdk>=3.0
slackeventsapi>=2.1.0
aprsd>=2.0.0

View File

@ -1,63 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --annotation-style=line --resolver=backtracking requirements.in
#
aprsd==2.6.1 # via -r requirements.in
aprslib==0.7.2 # via aprsd
attrs==22.1.0 # via aprsd, ax253, kiss3
ax253==0.1.5.post1 # via aprsd, kiss3
beautifulsoup4==4.11.1 # via aprsd
bidict==0.22.0 # via aprsd, python-socketio
bitarray==2.6.0 # via aprsd, ax253, kiss3
certifi==2022.12.7 # via aprsd, requests
cffi==1.15.1 # via aprsd, cryptography
charset-normalizer==2.1.1 # via aprsd, requests
click==8.1.3 # via aprsd, click-completion, flask
click-completion==0.5.2 # via aprsd
commonmark==0.9.1 # via aprsd, rich
cryptography==38.0.4 # via aprsd, pyopenssl
dnspython==2.2.1 # via aprsd, eventlet
eventlet==0.33.2 # via aprsd
flask==2.1.2 # via aprsd, flask-classful, flask-httpauth, flask-socketio, slackeventsapi
flask-classful==0.14.2 # via aprsd
flask-httpauth==4.7.0 # via aprsd
flask-socketio==5.3.2 # via aprsd
greenlet==2.0.1 # via aprsd, eventlet
idna==3.4 # via aprsd, requests
imapclient==2.3.1 # via aprsd
importlib-metadata==5.1.0 # via aprsd, ax253, flask, kiss3
itsdangerous==2.1.2 # via aprsd, flask
jinja2==3.1.2 # via aprsd, click-completion, flask
kiss3==8.0.0 # via aprsd
markupsafe==2.1.1 # via aprsd, jinja2
pbr==5.11.0 # via -r requirements.in, aprsd
pluggy==1.0.0 # via aprsd
pycparser==2.21 # via aprsd, cffi
pyee==9.0.4 # via slackeventsapi
pygments==2.13.0 # via aprsd, rich
pyopenssl==22.1.0 # via aprsd
pyserial==3.5 # via aprsd, pyserial-asyncio
pyserial-asyncio==0.6 # via aprsd, kiss3
python-engineio==4.3.4 # via aprsd, python-socketio
python-socketio==5.7.2 # via aprsd, flask-socketio
pytz==2022.6 # via aprsd
pyyaml==6.0 # via aprsd
requests==2.28.1 # via aprsd, update-checker
rich==12.6.0 # via aprsd
shellingham==1.5.0 # via aprsd, click-completion
six==1.16.0 # via aprsd, click-completion, eventlet, imapclient
slack-sdk==3.19.5 # via -r requirements.in
slackeventsapi==3.0.1 # via -r requirements.in
soupsieve==2.3.2.post1 # via aprsd, beautifulsoup4
tabulate==0.9.0 # via aprsd
thesmuggler==1.0.1 # via aprsd
typing-extensions==4.4.0 # via pyee
ua-parser==0.16.1 # via aprsd, user-agents
update-checker==0.18.0 # via aprsd
urllib3==1.26.13 # via aprsd, requests
user-agents==2.2.0 # via aprsd
werkzeug==2.1.2 # via aprsd, flask
wrapt==1.14.1 # via aprsd
zipp==3.11.0 # via aprsd, importlib-metadata
pbr
slack_sdk>=3.0
slackeventsapi>=2.1.0
aprsd
oslo_config

View File

@ -17,6 +17,10 @@ description_file =
README.rst
summary = Amateur radio APRS daemon which listens for messages and responds
[options.entry_points]
oslo.config.opts =
aprsd_slack_plugin.conf = aprsd_slack_plugin.conf.opts:list_opts
[global]
setup-hooks =
pbr.hooks.setup_hook

View File

@ -1,6 +1,9 @@
import unittest
from unittest import mock
from aprsd import conf # noqa
from aprsd_slack_plugin import conf as plugin_conf # noqa
from aprsd_slack_plugin import location_plugin
@ -9,10 +12,6 @@ class TestPlugin(unittest.TestCase):
def test_plugin(self, mock_command):
mock_command.return_value = ""
config = {
"slack": {"signing_secret": "something", "bot_token": "sometoken", "channel": "hemna"},
}
p = location_plugin.SlackLocationPlugin(config)
p = location_plugin.SlackLocationPlugin()
packet = {"from": "WB4BOR", "message_text": "location"}
p.filter(packet)

21
tox.ini
View File

@ -11,17 +11,14 @@ extend-exclude =
# This section is not needed if not using GitHub Actions for CI.
[gh-actions]
python =
3.7: py37
3.8: py38, fmt-check, lint
3.9: py39
[tox]
# These are the default environments that will be run
# when ``tox`` is run without arguments.
envlist =
fmt-check
lint
py{37,38,39}
py{39}
skip_missing_interpreters = true
# Activate isolated build environment. tox will use a virtual environment
@ -64,22 +61,6 @@ commands =
sphinx-apidoc --force --output-dir apidoc {toxinidir}/aprsd_slack_plugin
sphinx-build -a -W . _build
[testenv:fmt]
skip_install = true
deps =
-r{toxinidir}/requirements-dev.txt
commands =
isort aprsd_slack_plugin tests
black aprsd_slack_plugin tests
[testenv:fmt-check]
skip_install = true
deps =
-r{toxinidir}/requirements-dev.txt
commands =
isort --check-only aprsd_slack_plugin tests
black --check aprsd_slack_plugin tests
[testenv:licenses]
skip_install = true
recreate = true