Compare commits

...

15 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
Hemna 53d45e9e74 1.0.5 2022-12-18 13:35:10 -05:00
Hemna 8cef8fbdbf cleanup 2022-12-18 13:18:32 -05:00
Hemna c18823cf88 fix tox runs 2022-12-18 13:18:32 -05:00
Hemna 41b7c27a63 More cleanup 2022-12-18 13:18:32 -05:00
Walter A. Boring IV f6a456a586
Create FUNDING.yml 2021-12-14 11:15:57 -05:00
21 changed files with 397 additions and 443 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: wb4bor
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -17,31 +17,7 @@ repos:
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/asottile/add-trailing-comma
rev: v2.0.2
- repo: https://github.com/dizballanze/gray
rev: v0.10.1
hooks:
- id: add-trailing-comma
args: [--py36-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v2.7.4
hooks:
- id: pyupgrade
args:
- --py3-plus
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.7.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 20.8b1
hooks:
- id: black
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.4
hooks:
- id: flake8
additional_dependencies: [flake8-bugbear]
- id: gray

View File

@ -1 +1,2 @@
Hemna <waboring@hemna.com>
Walter A. Boring IV <waboring@hemna.com>

View File

@ -1,8 +1,35 @@
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
* Create FUNDING.yml
* update for new aprsd
* update requirements.txt so it doesn't have so many
* fixed build issues
* Updated to work with 2.0.0
* Added new notification and location plugin
* Fixed to work with utils\_refactor
* Update for new plugin interface. Add Notify plugin
* Added geo description in location
* fixed tests for tox
@ -10,10 +37,6 @@ CHANGES
* prep for release
* new updated location plugin
* Updated slack formatting
v1.0.4
------
* Updates for v1.0.4 release
* Added Makefile, pre-commit. Also update for 1.5.0

View File

@ -1,50 +1,73 @@
.PHONY: virtual dev build-requirements black isort flake8
REQUIREMENTS_TXT ?= requirements.txt dev-requirements.txt
REQUIREMENTS_TXT ?= requirements.txt requirements-dev.txt
.DEFAULT_GOAL := help
.PHONY: help dev test
include Makefile.venv
Makefile.venv:
curl \
-o Makefile.fetched \
-L "https://github.com/sio/Makefile.venv/raw/v2020.08.14/Makefile.venv"
-o Makefile.fetched \
-L "https://github.com/sio/Makefile.venv/raw/v2020.08.14/Makefile.venv"
echo "5afbcf51a82f629cd65ff23185acde90ebe4dec889ef80bbdc12562fbd0b2611 *Makefile.fetched" \
| sha256sum --check - \
&& mv Makefile.fetched Makefile.venv
| sha256sum --check - \
&& mv Makefile.fetched Makefile.venv
all: pip dev
help: # Help for the Makefile
@egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
.PHONY: dev
dev: venv
$(VENV)/pre-commit install
dev: venv ## Create the virtualenv with all the requirements installed
.PHONY: docs
docs: build
cp README.rst docs/readme.rst
cp Changelog docs/changelog.rst
tox -edocs
clean: clean-venv
rm -rf dist/*
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
.PHONY: test
test: dev
clean-build: ## remove build artifacts
rm -fr build/
rm -fr dist/
rm -fr .eggs/
find . -name '*.egg-info' -exec rm -fr {} +
find . -name '*.egg' -exec rm -f {} +
clean-pyc: ## remove Python file artifacts
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
find . -name '__pycache__' -exec rm -fr {} +
clean-test: ## remove test and coverage artifacts
rm -fr .tox/
rm -f .coverage
rm -fr htmlcov/
rm -fr .pytest_cache
coverage: ## check code coverage quickly with the default Python
coverage run --source aprsd_repeat_plugins setup.py test
coverage report -m
coverage html
$(BROWSER) htmlcov/index.html
test: dev ## Run all the tox tests
tox -p all
build: test
build: test ## Make the build artifact prior to doing an upload
$(VENV)/python3 setup.py sdist bdist_wheel
$(VENV)/twine check dist/*
upload: build
upload: build ## Upload a new version of the plugin
$(VENV)/twine upload dist/*
update-requirements: dev
$(VENV)/pip-compile requirements.in
$(VENV)/pip-compile dev-requirements.in
check: dev # Code format check with isort and black
tox -efmt-check
check: dev ## Code format check with tox and pep8
tox -epep8
fix: dev # fixes code formatting with isort and black
fix: dev ## fixes code formatting with gray
tox -efmt
update-requirements: dev ## Update the requirements.txt and dev-requirements.txt files
rm requirements.txt
rm requirements-dev.txt
touch requirements.txt
touch requirements-dev.txt
$(VENV)/pip-compile --resolver backtracking --annotation-style line requirements.in
$(VENV)/pip-compile --resolver backtracking --annotation-style line requirements-dev.in

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

@ -1,281 +0,0 @@
#
# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#
# pip-compile dev-requirements.in
#
alabaster==0.7.12
# via sphinx
appdirs==1.4.4
# via
# black
# virtualenv
aprsd==2.0.0
# via -r dev-requirements.in
aprslib==0.6.47
# via aprsd
attrs==21.2.0
# via pytest
babel==2.9.1
# via sphinx
backoff==1.10.0
# via
# aprsd
# opencage
black==21.6b0
# via -r dev-requirements.in
certifi==2020.12.5
# via
# aprsd
# requests
cffi==1.14.5
# via
# aprsd
# cryptography
cfgv==3.3.0
# via pre-commit
chardet==4.0.0
# via
# aprsd
# requests
click==7.1.2
# via
# aprsd
# black
# click-completion
# flask
# pip-tools
click-completion==0.5.2
# via aprsd
coverage==5.5
# via pytest-cov
cryptography==3.4.7
# via
# aprsd
# pyopenssl
distlib==0.3.2
# via virtualenv
dnspython==2.1.0
# via
# aprsd
# py3-validate-email
docutils==0.17.1
# via sphinx
filelock==3.0.12
# via
# aprsd
# py3-validate-email
# tox
# virtualenv
flake8==3.9.2
# via
# -r dev-requirements.in
# flake8-polyfill
flake8-polyfill==1.0.2
# via pep8-naming
flask==1.1.2
# via
# aprsd
# flask-classful
# flask-httpauth
flask-classful==0.14.2
# via aprsd
flask-httpauth==4.3.0
# via aprsd
identify==2.2.10
# via pre-commit
idna==2.10
# via
# aprsd
# py3-validate-email
# requests
imagesize==1.2.0
# via sphinx
imapclient==2.2.0
# via aprsd
iniconfig==1.1.1
# via pytest
isort==5.8.0
# via -r dev-requirements.in
itsdangerous==1.1.0
# via
# aprsd
# flask
jinja2==2.11.3
# via
# aprsd
# click-completion
# flask
# sphinx
lxml==4.6.3
# via
# aprsd
# yfinance
markupsafe==1.1.1
# via
# aprsd
# jinja2
mccabe==0.6.1
# via flake8
multitasking==0.0.9
# via
# aprsd
# yfinance
mypy==0.902
# via -r dev-requirements.in
mypy-extensions==0.4.3
# via
# black
# mypy
nodeenv==1.6.0
# via pre-commit
numpy==1.20.2
# via
# aprsd
# pandas
# yfinance
opencage==1.2.2
# via aprsd
packaging==20.9
# via
# pytest
# sphinx
# tox
pandas==1.2.4
# via
# aprsd
# yfinance
pathspec==0.8.1
# via black
pbr==5.6.0
# via
# -r dev-requirements.in
# aprsd
pep517==0.10.0
# via pip-tools
pep8-naming==0.11.1
# via -r dev-requirements.in
pip-tools==6.1.0
# via -r dev-requirements.in
pluggy==0.13.1
# via
# aprsd
# pytest
# tox
pre-commit==2.13.0
# via -r dev-requirements.in
py==1.10.0
# via
# pytest
# tox
py3-validate-email==0.2.16
# via aprsd
pycodestyle==2.7.0
# via flake8
pycparser==2.20
# via
# aprsd
# cffi
pyflakes==2.3.1
# via flake8
pygments==2.9.0
# via sphinx
pyopenssl==20.0.1
# via
# aprsd
# opencage
pyparsing==2.4.7
# via packaging
pytest==6.2.4
# via
# -r dev-requirements.in
# pytest-cov
pytest-cov==2.12.1
# via -r dev-requirements.in
python-dateutil==2.8.1
# via
# aprsd
# pandas
pytz==2021.1
# via
# aprsd
# babel
# pandas
pyyaml==5.4.1
# via
# aprsd
# pre-commit
regex==2021.4.4
# via black
requests==2.25.1
# via
# aprsd
# opencage
# sphinx
# update-checker
# yfinance
shellingham==1.4.0
# via
# aprsd
# click-completion
six==1.15.0
# via
# aprsd
# click-completion
# imapclient
# opencage
# pyopenssl
# python-dateutil
# tox
# virtualenv
snowballstemmer==2.1.0
# via sphinx
sphinx==4.0.2
# via -r dev-requirements.in
sphinxcontrib-applehelp==1.0.2
# via sphinx
sphinxcontrib-devhelp==1.0.2
# via sphinx
sphinxcontrib-htmlhelp==2.0.0
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
thesmuggler==1.0.1
# via aprsd
toml==0.10.2
# via
# black
# mypy
# pep517
# pre-commit
# pytest
# pytest-cov
# tox
tox==3.23.1
# via -r dev-requirements.in
typing-extensions==3.10.0.0
# via mypy
update-checker==0.18.0
# via aprsd
urllib3==1.26.5
# via
# aprsd
# requests
virtualenv==20.4.7
# via
# pre-commit
# tox
werkzeug==1.0.1
# via
# aprsd
# flask
yfinance==0.1.59
# via aprsd
# The following packages are considered to be unsafe in a requirements file:
# pip
# setuptools

2
gray.conf Normal file
View File

@ -0,0 +1,2 @@
formatters = add-trailing-comma,autoflake,fixit,isort,pyupgrade,unify
min-python-version = 3.8

76
requirements-dev.txt Normal file
View File

@ -0,0 +1,76 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# pip-compile --annotation-style=line --resolver=backtracking requirements-dev.in
#
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==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
coverage[toml]==7.2.7 # via pytest-cov
distlib==0.3.6 # via 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
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==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==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
pyflakes==3.0.1 # via flake8
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.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
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.1 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.5 # via sphinx
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
# setuptools

View File

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

View File

@ -1,4 +1,5 @@
pbr
slack_sdk>=3.0
slackeventsapi>=2.1.0
aprsd>=2.0.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,22 +1,17 @@
import sys
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
if sys.version_info >= (3, 2):
from unittest import mock
else:
from unittest import mock
class TestPlugin(unittest.TestCase):
@mock.patch.object(location_plugin.SlackLocationPlugin, "command")
@mock.patch.object(location_plugin.SlackLocationPlugin, "filter")
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.command("KM6LYW", "location", 1)
p = location_plugin.SlackLocationPlugin()
packet = {"from": "WB4BOR", "message_text": "location"}
p.filter(packet)

29
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
@ -32,7 +29,7 @@ isolated_build = true
[testenv]
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
-r{toxinidir}/requirements-dev.txt
commands =
# Use -bb to enable BytesWarnings as error to catch str/bytes misuse.
# Use -Werror to treat warnings as errors.
@ -42,14 +39,14 @@ commands =
skip_install = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
-r{toxinidir}/requirements-dev.txt
commands =
mypy src tests
[testenv:lint]
skip_install = true
deps =
-r{toxinidir}/dev-requirements.txt
-r{toxinidir}/requirements-dev.txt
commands =
flake8 aprsd_slack_plugin tests
@ -57,29 +54,13 @@ commands =
skip_install = true
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
-r{toxinidir}/requirements-dev.txt
changedir = {toxinidir}/docs
commands =
{envpython} clean_docs.py
sphinx-apidoc --force --output-dir apidoc {toxinidir}/aprsd_slack_plugin
sphinx-build -a -W . _build
[testenv:fmt]
skip_install = true
deps =
-r{toxinidir}/dev-requirements.txt
commands =
isort aprsd_slack_plugin tests
black aprsd_slack_plugin tests
[testenv:fmt-check]
skip_install = true
deps =
-r{toxinidir}/dev-requirements.txt
commands =
isort --check-only aprsd_slack_plugin tests
black --check aprsd_slack_plugin tests
[testenv:licenses]
skip_install = true
recreate = true