Use Gray instead of Black for code formatting.

The Black code formatter sucks with respect to function
declarations with a lot of params.  Completely unreadable.
This commit is contained in:
Hemna 2021-08-23 12:14:19 -04:00
parent d6643a8e96
commit e175f77347
39 changed files with 286 additions and 278 deletions

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

@ -12,4 +12,5 @@
import pbr.version
__version__ = pbr.version.VersionInfo("aprsd").version_string()

View File

@ -2,19 +2,17 @@ import logging
import select
import time
import aprsd
from aprsd import stats
import aprslib
from aprslib import is_py3
from aprslib.exceptions import (
ConnectionDrop,
ConnectionError,
GenericError,
LoginError,
ParseError,
ConnectionDrop, ConnectionError, GenericError, LoginError, ParseError,
UnknownFormat,
)
import aprsd
from aprsd import stats
LOG = logging.getLogger("APRSD")
@ -67,15 +65,15 @@ class Client:
connected = True
backoff = 1
except LoginError as e:
LOG.error("Failed to login to APRS-IS Server '{}'".format(e))
LOG.error(f"Failed to login to APRS-IS Server '{e}'")
connected = False
raise e
except Exception as e:
LOG.error("Unable to connect to APRS-IS server. '{}' ".format(e))
LOG.error(f"Unable to connect to APRS-IS server. '{e}' ")
time.sleep(backoff)
backoff = backoff * 2
continue
LOG.debug("Logging in to APRS-IS with user '%s'" % user)
LOG.debug(f"Logging in to APRS-IS with user '{user}'")
return aprs_client
@ -99,7 +97,7 @@ class Aprsdis(aprslib.IS):
try:
self.sock.setblocking(0)
except OSError as e:
self.logger.error("socket error when setblocking(0): %s" % str(e))
self.logger.error(f"socket error when setblocking(0): {str(e)}")
raise aprslib.ConnectionDrop("connection dropped")
while not self.thread_stop:
@ -169,14 +167,14 @@ class Aprsdis(aprslib.IS):
else:
server_string = e.replace("server ", "")
self.logger.info("Connected to {}".format(server_string))
self.logger.info(f"Connected to {server_string}")
self.server_string = server_string
stats.APRSDStats().set_aprsis_server(server_string)
if callsign == "":
raise LoginError("Server responded with empty callsign???")
if callsign != self.callsign:
raise LoginError("Server: %s" % test)
raise LoginError(f"Server: {test}")
if status != "verified," and self.passwd != "-1":
raise LoginError("Password is incorrect")
@ -191,7 +189,7 @@ class Aprsdis(aprslib.IS):
raise
except Exception as e:
self.close()
self.logger.error("Failed to login '{}'".format(e))
self.logger.error(f"Failed to login '{e}'")
raise LoginError("Failed to login")
def consumer(self, callback, blocking=True, immortal=False, raw=False):

View File

@ -9,11 +9,13 @@ from logging.handlers import RotatingFileHandler
import os
import sys
import click
import click_completion
# local imports here
import aprsd
from aprsd import client, email, plugin, utils
import click
import click_completion
# setup the global logger
# logging.basicConfig(level=logging.DEBUG) # level=10
@ -48,7 +50,7 @@ Available shell types:
%s
Default type: auto
""" % "\n ".join(
"{:<12} {}".format(k, click_completion.core.shells[k])
f"{k:<12} {click_completion.core.shells[k]}"
for k in sorted(click_completion.core.shells.keys())
)
@ -110,7 +112,7 @@ def install(append, case_insensitive, shell, path):
append=append,
extra_env=extra_env,
)
click.echo("{} completion installed in {}".format(shell, path))
click.echo(f"{shell} completion installed in {path}")
# Setup the logging faciility
@ -180,10 +182,10 @@ def test_plugin(
email.CONFIG = config
setup_logging(config, loglevel, False)
LOG.info("Test APRSD PLugin version: {}".format(aprsd.__version__))
LOG.info(f"Test APRSD PLugin version: {aprsd.__version__}")
if type(message) is tuple:
message = " ".join(message)
LOG.info("P'{}' F'{}' C'{}'".format(plugin_path, fromcall, message))
LOG.info(f"P'{plugin_path}' F'{fromcall}' C'{message}'")
client.Client(config)
pm = plugin.PluginManager(config)
@ -192,7 +194,7 @@ def test_plugin(
packet = {"from": fromcall, "message_text": message, "msgNo": 1}
reply = obj.run(packet)
LOG.info("Result = '{}'".format(reply))
LOG.info(f"Result = '{reply}'")
if __name__ == "__main__":

View File

@ -7,10 +7,12 @@ import re
import smtplib
import time
from aprsd import messaging, stats, threads, trace
import imapclient
from validate_email import validate_email
from aprsd import messaging, stats, threads, trace
LOG = logging.getLogger("APRSD")
# This gets forced set from main.py prior to being used internally
@ -45,7 +47,7 @@ def _imap_connect():
)
except (imaplib.IMAP4.error, Exception) as e:
msg = getattr(e, "message", repr(e))
LOG.error("Failed to login {}".format(msg))
LOG.error(f"Failed to login {msg}")
return
server.select_folder("INBOX")
@ -87,7 +89,7 @@ def _smtp_connect():
LOG.error("Couldn't connect to SMTP Server")
return
LOG.debug("Connected to smtp host {}".format(msg))
LOG.debug(f"Connected to smtp host {msg}")
debug = CONFIG["aprsd"]["email"]["smtp"].get("debug", False)
if debug:
@ -103,7 +105,7 @@ def _smtp_connect():
LOG.error("Couldn't connect to SMTP Server")
return
LOG.debug("Logged into SMTP server {}".format(msg))
LOG.debug(f"Logged into SMTP server {msg}")
return server
@ -118,7 +120,7 @@ def validate_shortcuts(config):
)
delete_keys = []
for key in shortcuts:
LOG.info("Validating {}:{}".format(key, shortcuts[key]))
LOG.info(f"Validating {key}:{shortcuts[key]}")
is_valid = validate_email(
email_address=shortcuts[key],
check_regex=True,
@ -183,7 +185,7 @@ def parse_email(msgid, data, server):
from_addr = f.group(1)
else:
from_addr = "noaddr"
LOG.debug("Got a message from '{}'".format(from_addr))
LOG.debug(f"Got a message from '{from_addr}'")
try:
m = server.fetch([msgid], ["RFC822"])
except Exception as e:
@ -317,7 +319,7 @@ def resend_email(count, fromcall):
month = date.strftime("%B")[:3] # Nov, Mar, Apr
day = date.day
year = date.year
today = "{}-{}-{}".format(day, month, year)
today = f"{day}-{month}-{year}"
shortcuts = CONFIG["aprsd"]["email"]["shortcuts"]
# swap key/value
@ -434,7 +436,7 @@ class APRSDEmailThread(threads.APRSDThread):
month = date.strftime("%B")[:3] # Nov, Mar, Apr
day = date.day
year = date.year
today = "{}-{}-{}".format(day, month, year)
today = f"{day}-{month}-{year}"
server = None
try:
@ -450,7 +452,7 @@ class APRSDEmailThread(threads.APRSDThread):
except Exception as e:
LOG.exception("IMAP failed to search for messages since today.", e)
continue
LOG.debug("{} messages received today".format(len(messages)))
LOG.debug(f"{len(messages)} messages received today")
try:
_msgs = server.fetch(messages, ["ENVELOPE"])

View File

@ -7,6 +7,7 @@ import time
from aprsd import utils
# command line args
parser = argparse.ArgumentParser()
parser.add_argument(
@ -56,7 +57,7 @@ class MyAPRSTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
LOG.debug("{} wrote:".format(self.client_address[0]))
LOG.debug(f"{self.client_address[0]} wrote:")
LOG.debug(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
@ -73,7 +74,7 @@ def main():
ip = CONFIG["aprs"]["host"]
port = CONFIG["aprs"]["port"]
LOG.info("Start server listening on {}:{}".format(args.ip, args.port))
LOG.info(f"Start server listening on {args.ip}:{args.port}")
with socketserver.TCPServer((ip, port), MyAPRSTCPHandler) as server:
server.serve_forever()

View File

@ -5,13 +5,15 @@ from logging import NullHandler
from logging.handlers import RotatingFileHandler
import sys
import aprsd
from aprsd import messaging, packets, plugin, stats, utils
import flask
import flask_classful
from flask_httpauth import HTTPBasicAuth
from werkzeug.security import check_password_hash, generate_password_hash
import aprsd
from aprsd import messaging, packets, plugin, stats, utils
LOG = logging.getLogger("APRSD")
auth = HTTPBasicAuth()

View File

@ -13,13 +13,15 @@ import os
import re
import sys
# local imports here
import aprsd
from aprsd import utils
import click
import click_completion
import requests
# local imports here
import aprsd
from aprsd import utils
# setup the global logger
# logging.basicConfig(level=logging.DEBUG) # level=10
LOG = logging.getLogger("APRSD")
@ -53,7 +55,7 @@ Available shell types:
%s
Default type: auto
""" % "\n ".join(
"{:<12} {}".format(k, click_completion.core.shells[k])
f"{k:<12} {click_completion.core.shells[k]}"
for k in sorted(click_completion.core.shells.keys())
)
@ -115,7 +117,7 @@ def install(append, case_insensitive, shell, path):
append=append,
extra_env=extra_env,
)
click.echo("{} completion installed in {}".format(shell, path))
click.echo(f"{shell} completion installed in {path}")
# Setup the logging faciility
@ -192,14 +194,14 @@ def check(loglevel, config_file, health_url, timeout):
config = utils.parse_config(config_file)
setup_logging(config, loglevel, False)
LOG.debug("APRSD HealthCheck version: {}".format(aprsd.__version__))
LOG.debug(f"APRSD HealthCheck version: {aprsd.__version__}")
try:
url = health_url
response = requests.get(url, timeout=timeout)
response.raise_for_status()
except Exception as ex:
LOG.error("Failed to fetch healthcheck url '{}' : '{}'".format(url, ex))
LOG.error(f"Failed to fetch healthcheck url '{url}' : '{ex}'")
sys.exit(-1)
else:
stats = json.loads(response.text)
@ -212,7 +214,7 @@ def check(loglevel, config_file, health_url, timeout):
max_timeout = {"hours": 0.0, "minutes": 5, "seconds": 0}
max_delta = datetime.timedelta(**max_timeout)
if d > max_delta:
LOG.error("Email thread is very old! {}".format(d))
LOG.error(f"Email thread is very old! {d}")
sys.exit(-1)
aprsis_last_update = stats["stats"]["aprs-is"]["last_update"]
@ -221,7 +223,7 @@ def check(loglevel, config_file, health_url, timeout):
max_timeout = {"hours": 0.0, "minutes": 5, "seconds": 0}
max_delta = datetime.timedelta(**max_timeout)
if d > max_delta:
LOG.error("APRS-IS last update is very old! {}".format(d))
LOG.error(f"APRS-IS last update is very old! {d}")
sys.exit(-1)
sys.exit(0)

View File

@ -29,14 +29,16 @@ import signal
import sys
import time
# local imports here
import aprsd
from aprsd import client, messaging, stats, threads, trace, utils
import aprslib
from aprslib.exceptions import LoginError
import click
import click_completion
# local imports here
import aprsd
from aprsd import client, messaging, stats, threads, trace, utils
# setup the global logger
# logging.basicConfig(level=logging.DEBUG) # level=10
LOG = logging.getLogger("APRSD")
@ -78,7 +80,7 @@ Available shell types:
%s
Default type: auto
""" % "\n ".join(
"{:<12} {}".format(k, click_completion.core.shells[k])
f"{k:<12} {click_completion.core.shells[k]}"
for k in sorted(click_completion.core.shells.keys())
)
@ -140,7 +142,7 @@ def install(append, case_insensitive, shell, path):
append=append,
extra_env=extra_env,
)
click.echo("{} completion installed in {}".format(shell, path))
click.echo(f"{shell} completion installed in {path}")
def signal_handler(sig, frame):
@ -270,22 +272,22 @@ def listen(
messaging.CONFIG = config
setup_logging(config, loglevel, quiet)
LOG.info("APRSD TEST Started version: {}".format(aprsd.__version__))
LOG.info(f"APRSD TEST Started version: {aprsd.__version__}")
if type(command) is tuple:
command = " ".join(command)
if not quiet:
if raw:
LOG.info("L'{}' R'{}'".format(aprs_login, raw))
LOG.info(f"L'{aprs_login}' R'{raw}'")
else:
LOG.info("L'{}' To'{}' C'{}'".format(aprs_login, tocallsign, command))
LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
flat_config = utils.flatten_dict(config)
LOG.info("Using CONFIG values:")
for x in flat_config:
if "password" in x or "aprsd.web.users.admin" in x:
LOG.info("{} = XXXXXXXXXXXXXXXXXXX".format(x))
LOG.info(f"{x} = XXXXXXXXXXXXXXXXXXX")
else:
LOG.info("{} = {}".format(x, flat_config[x]))
LOG.info(f"{x} = {flat_config[x]}")
got_ack = False
got_response = False
@ -328,7 +330,7 @@ def listen(
),
)
else:
LOG.debug("Not old enough to notify {} < {}".format(d, max_delta))
LOG.debug(f"Not old enough to notify {d} < {max_delta}")
LOG.debug("Update last seen from {}".format(packet["from"]))
last_seen[packet["from"]] = now
else:
@ -339,7 +341,7 @@ def listen(
resp = packet.get("response", None)
if resp == "ack":
ack_num = packet.get("msgNo")
LOG.info("We saw an ACK {} Ignoring".format(ack_num))
LOG.info(f"We saw an ACK {ack_num} Ignoring")
# messaging.log_packet(packet)
got_ack = True
else:
@ -366,7 +368,7 @@ def listen(
# LOG.debug("Filter by '{}'".format(filter_str))
# aprs_client.set_filter(filter_str)
filter_str = "p/{}".format("/".join(watch_list))
LOG.debug("Filter by '{}'".format(filter_str))
LOG.debug(f"Filter by '{filter_str}'")
aprs_client.set_filter(filter_str)
while True:

View File

@ -30,25 +30,19 @@ import signal
import sys
import time
# local imports here
import aprsd
from aprsd import (
client,
email,
flask,
messaging,
packets,
plugin,
stats,
threads,
trace,
utils,
)
import aprslib
from aprslib.exceptions import LoginError
import click
import click_completion
# local imports here
import aprsd
from aprsd import (
client, email, flask, messaging, packets, plugin, stats, threads, trace,
utils,
)
# setup the global logger
# logging.basicConfig(level=logging.DEBUG) # level=10
LOG = logging.getLogger("APRSD")
@ -90,7 +84,7 @@ Available shell types:
%s
Default type: auto
""" % "\n ".join(
"{:<12} {}".format(k, click_completion.core.shells[k])
f"{k:<12} {click_completion.core.shells[k]}"
for k in sorted(click_completion.core.shells.keys())
)
@ -152,7 +146,7 @@ def install(append, case_insensitive, shell, path):
append=append,
extra_env=extra_env,
)
click.echo("{} completion installed in {}".format(shell, path))
click.echo(f"{shell} completion installed in {path}")
def signal_handler(sig, frame):
@ -325,14 +319,14 @@ def send_message(
messaging.CONFIG = config
setup_logging(config, loglevel, quiet)
LOG.info("APRSD Started version: {}".format(aprsd.__version__))
LOG.info(f"APRSD Started version: {aprsd.__version__}")
if type(command) is tuple:
command = " ".join(command)
if not quiet:
if raw:
LOG.info("L'{}' R'{}'".format(aprs_login, raw))
LOG.info(f"L'{aprs_login}' R'{raw}'")
else:
LOG.info("L'{}' To'{}' C'{}'".format(aprs_login, tocallsign, command))
LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
got_ack = False
got_response = False
@ -343,7 +337,7 @@ def send_message(
resp = packet.get("response", None)
if resp == "ack":
ack_num = packet.get("msgNo")
LOG.info("We got ack for our sent message {}".format(ack_num))
LOG.info(f"We got ack for our sent message {ack_num}")
messaging.log_packet(packet)
got_ack = True
else:
@ -471,15 +465,15 @@ def server(
LOG.warning(msg)
else:
LOG.info(msg)
LOG.info("APRSD Started version: {}".format(aprsd.__version__))
LOG.info(f"APRSD Started version: {aprsd.__version__}")
flat_config = utils.flatten_dict(config)
LOG.info("Using CONFIG values:")
for x in flat_config:
if "password" in x or "aprsd.web.users.admin" in x:
LOG.info("{} = XXXXXXXXXXXXXXXXXXX".format(x))
LOG.info(f"{x} = XXXXXXXXXXXXXXXXXXX")
else:
LOG.info("{} = {}".format(x, flat_config[x]))
LOG.info(f"{x} = {flat_config[x]}")
if config["aprsd"].get("trace", False):
trace.setup_tracing(["method", "api"])

View File

@ -11,6 +11,7 @@ import time
from aprsd import client, stats, threads, trace, utils
LOG = logging.getLogger("APRSD")
# What to return from a plugin if we have processed the message
@ -81,7 +82,7 @@ class MsgTrack:
with self.lock:
result = "{"
for key in self.track.keys():
result += "{}: {}, ".format(key, str(self.track[key]))
result += f"{key}: {str(self.track[key])}, "
result += "}"
return result
@ -105,9 +106,9 @@ class MsgTrack:
def save(self):
"""Save any queued to disk?"""
LOG.debug("Save tracker to disk? {}".format(len(self)))
LOG.debug(f"Save tracker to disk? {len(self)}")
if len(self) > 0:
LOG.info("Saving {} tracking messages to disk".format(len(self)))
LOG.info(f"Saving {len(self)} tracking messages to disk")
pickle.dump(self.dump(), open(utils.DEFAULT_SAVE_FILE, "wb+"))
else:
LOG.debug(
@ -239,7 +240,6 @@ class Message(metaclass=abc.ABCMeta):
@abc.abstractmethod
def send(self):
"""Child class must declare."""
pass
class RawMessage(Message):
@ -348,7 +348,7 @@ class TextMessage(Message):
def send(self):
tracker = MsgTrack()
tracker.add(self)
LOG.debug("Length of MsgTrack is {}".format(len(tracker)))
LOG.debug(f"Length of MsgTrack is {len(tracker)}")
thread = SendMessageThread(message=self)
thread.start()
@ -370,7 +370,7 @@ class SendMessageThread(threads.APRSDThread):
def __init__(self, message):
self.msg = message
name = self.msg.message[:5]
super().__init__("SendMessage-{}-{}".format(self.msg.id, name))
super().__init__(f"SendMessage-{self.msg.id}-{name}")
def loop(self):
"""Loop until a message is acked or it gets delayed.
@ -463,7 +463,7 @@ class AckMessage(Message):
)
def send(self):
LOG.debug("Send ACK({}:{}) to radio.".format(self.tocall, self.id))
LOG.debug(f"Send ACK({self.tocall}:{self.id}) to radio.")
thread = SendAckThread(self)
thread.start()
@ -486,7 +486,7 @@ class AckMessage(Message):
class SendAckThread(threads.APRSDThread):
def __init__(self, ack):
self.ack = ack
super().__init__("SendAck-{}".format(self.ack.id))
super().__init__(f"SendAck-{self.ack.id}")
@trace.trace
def loop(self):
@ -511,7 +511,7 @@ class SendAckThread(threads.APRSDThread):
# It's time to try to send it again
send_now = True
else:
LOG.debug("Still wating. {}".format(delta))
LOG.debug(f"Still wating. {delta}")
else:
send_now = True
@ -555,16 +555,8 @@ def log_packet(packet):
def log_message(
header,
raw,
message,
tocall=None,
fromcall=None,
msg_num=None,
retry_number=None,
ack=None,
packet_type=None,
uuid=None,
header, raw, message, tocall=None, fromcall=None, msg_num=None,
retry_number=None, ack=None, packet_type=None, uuid=None,
):
"""
@ -581,36 +573,36 @@ def log_message(
log_list = [""]
if retry_number:
# LOG.info(" {} _______________(TX:{})".format(header, retry_number))
log_list.append(" {} _______________(TX:{})".format(header, retry_number))
log_list.append(f" {header} _______________(TX:{retry_number})")
else:
# LOG.info(" {} _______________".format(header))
log_list.append(" {} _______________".format(header))
log_list.append(f" {header} _______________")
# LOG.info(" Raw : {}".format(raw))
log_list.append(" Raw : {}".format(raw))
log_list.append(f" Raw : {raw}")
if packet_type:
# LOG.info(" Packet : {}".format(packet_type))
log_list.append(" Packet : {}".format(packet_type))
log_list.append(f" Packet : {packet_type}")
if tocall:
# LOG.info(" To : {}".format(tocall))
log_list.append(" To : {}".format(tocall))
log_list.append(f" To : {tocall}")
if fromcall:
# LOG.info(" From : {}".format(fromcall))
log_list.append(" From : {}".format(fromcall))
log_list.append(f" From : {fromcall}")
if ack:
# LOG.info(" Ack : {}".format(ack))
log_list.append(" Ack : {}".format(ack))
log_list.append(f" Ack : {ack}")
else:
# LOG.info(" Message : {}".format(message))
log_list.append(" Message : {}".format(message))
log_list.append(f" Message : {message}")
if msg_num:
# LOG.info(" Msg number : {}".format(msg_num))
log_list.append(" Msg number : {}".format(msg_num))
log_list.append(f" Msg number : {msg_num}")
if uuid:
log_list.append(" UUID : {}".format(uuid))
log_list.append(f" UUID : {uuid}")
# LOG.info(" {} _______________ Complete".format(header))
log_list.append(" {} _______________ Complete".format(header))
log_list.append(f" {header} _______________ Complete")
LOG.info("\n".join(log_list))

View File

@ -5,6 +5,7 @@ import time
from aprsd import utils
LOG = logging.getLogger("APRSD")
PACKET_TYPE_MESSAGE = "message"

View File

@ -11,6 +11,7 @@ import threading
import pluggy
from thesmuggler import smuggle
# setup the global logger
LOG = logging.getLogger("APRSD")
@ -40,7 +41,6 @@ class APRSDCommandSpec:
@hookspec
def run(self, packet):
"""My special little hook that you can customize."""
pass
class APRSDNotificationPluginBase(metaclass=abc.ABCMeta):
@ -70,7 +70,6 @@ class APRSDNotificationPluginBase(metaclass=abc.ABCMeta):
This will get called when a packet is seen by a callsign
registered in the watch list in the config file."""
pass
class APRSDMessagePluginBase(metaclass=abc.ABCMeta):
@ -119,7 +118,6 @@ class APRSDMessagePluginBase(metaclass=abc.ABCMeta):
To reply with a message over the air, return a string
to send.
"""
pass
class PluginManager:
@ -152,7 +150,7 @@ class PluginManager:
def load_plugins_from_path(self, module_path):
if not os.path.exists(module_path):
LOG.error("plugin path '{}' doesn't exist.".format(module_path))
LOG.error(f"plugin path '{module_path}' doesn't exist.")
return None
dir_path = os.path.realpath(module_path)
@ -163,8 +161,8 @@ class PluginManager:
for path, _subdirs, files in os.walk(dir_path):
for name in files:
if fnmatch.fnmatch(name, pattern):
LOG.debug("MODULE? '{}' '{}'".format(name, path))
module = smuggle("{}/{}".format(path, name))
LOG.debug(f"MODULE? '{name}' '{path}'")
module = smuggle(f"{path}/{name}")
for mem_name, obj in inspect.getmembers(module):
if inspect.isclass(obj) and self.is_plugin(obj):
self.obj_list.append(
@ -196,7 +194,7 @@ class PluginManager:
module = importlib.import_module(module_name)
module = importlib.reload(module)
except Exception as ex:
LOG.error("Failed to load Plugin '{}' : '{}'".format(module_name, ex))
LOG.error(f"Failed to load Plugin '{module_name}' : '{ex}'")
return
assert hasattr(module, class_name), "class {} is not in {}".format(
@ -238,7 +236,7 @@ class PluginManager:
)
self._pluggy_msg_pm.register(plugin_obj)
except Exception as ex:
LOG.exception("Couldn't load plugin '{}'".format(plugin_name), ex)
LOG.exception(f"Couldn't load plugin '{plugin_name}'", ex)
def _load_notify_plugin(self, plugin_name):
"""
@ -262,7 +260,7 @@ class PluginManager:
)
self._pluggy_notify_pm.register(plugin_obj)
except Exception as ex:
LOG.exception("Couldn't load plugin '{}'".format(plugin_name), ex)
LOG.exception(f"Couldn't load plugin '{plugin_name}'", ex)
def reload_plugins(self):
with self.lock:

View File

@ -4,11 +4,12 @@ import logging
import requests
LOG = logging.getLogger("APRSD")
def get_aprs_fi(api_key, callsign):
LOG.debug("Fetch aprs.fi location for '{}'".format(callsign))
LOG.debug(f"Fetch aprs.fi location for '{callsign}'")
try:
url = (
"http://api.aprs.fi/api/get?"
@ -24,13 +25,13 @@ def get_aprs_fi(api_key, callsign):
def get_weather_gov_for_gps(lat, lon):
LOG.debug("Fetch station at {}, {}".format(lat, lon))
LOG.debug(f"Fetch station at {lat}, {lon}")
try:
url2 = (
"https://forecast.weather.gov/MapClick.php?lat=%s"
"&lon=%s&FcstType=json" % (lat, lon)
)
LOG.debug("Fetching weather '{}'".format(url2))
LOG.debug(f"Fetching weather '{url2}'")
response = requests.get(url2)
except Exception as e:
LOG.error(e)
@ -41,7 +42,7 @@ def get_weather_gov_for_gps(lat, lon):
def get_weather_gov_metar(station):
LOG.debug("Fetch metar for station '{}'".format(station))
LOG.debug(f"Fetch metar for station '{station}'")
try:
url = "https://api.weather.gov/stations/{}/observations/latest".format(
station,
@ -55,7 +56,7 @@ def get_weather_gov_metar(station):
def fetch_openweathermap(api_key, lat, lon, units="metric", exclude=None):
LOG.debug("Fetch openweathermap for {}, {}".format(lat, lon))
LOG.debug(f"Fetch openweathermap for {lat}, {lon}")
if not exclude:
exclude = "minutely,hourly,daily,alerts"
try:

View File

@ -4,6 +4,7 @@ import time
from aprsd import email, messaging, plugin, trace
LOG = logging.getLogger("APRSD")
@ -68,11 +69,11 @@ class EmailPlugin(plugin.APRSDMessagePluginBase):
if timedelta < 300: # five minutes
too_soon = 1
if not too_soon or ack == 0:
LOG.info("Send email '{}'".format(content))
LOG.info(f"Send email '{content}'")
send_result = email.send_email(to_addr, content)
reply = messaging.NULL_MESSAGE
if send_result != 0:
reply = "-{} failed".format(to_addr)
reply = f"-{to_addr} failed"
# messaging.send_message(fromcall, "-" + to_addr + " failed")
else:
# clear email sent dictionary if somehow goes over 100

View File

@ -4,6 +4,7 @@ import subprocess
from aprsd import plugin, trace
LOG = logging.getLogger("APRSD")
@ -45,7 +46,7 @@ class FortunePlugin(plugin.APRSDMessagePluginBase):
.replace("\t", " ")
)
except subprocess.CalledProcessError as ex:
reply = "Fortune command failed '{}'".format(ex.output)
reply = f"Fortune command failed '{ex.output}'"
else:
reply = output

View File

@ -4,6 +4,7 @@ import time
from aprsd import plugin, plugin_utils, trace, utils
LOG = logging.getLogger("APRSD")
@ -25,7 +26,7 @@ class LocationPlugin(plugin.APRSDMessagePluginBase):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
@ -42,10 +43,10 @@ class LocationPlugin(plugin.APRSDMessagePluginBase):
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"
@ -67,11 +68,11 @@ class LocationPlugin(plugin.APRSDMessagePluginBase):
try:
wx_data = plugin_utils.get_weather_gov_for_gps(lat, lon)
except Exception as ex:
LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(ex))
LOG.error(f"Couldn't fetch forecast.weather.gov '{ex}'")
wx_data = {"location": {"areaDescription": "Unknown Location"}}
if "location" not in wx_data:
LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(wx_data))
LOG.error(f"Couldn't fetch forecast.weather.gov '{wx_data}'")
wx_data = {"location": {"areaDescription": "Unknown Location"}}
reply = "{}: {} {}' {},{} {}h ago".format(

View File

@ -2,6 +2,7 @@ import logging
from aprsd import messaging, packets, plugin
LOG = logging.getLogger("APRSD")
@ -40,7 +41,7 @@ class NotifySeenPlugin(plugin.APRSDNotificationPluginBase):
packet_type = packets.get_packet_type(packet)
# we shouldn't notify the alert user that they are online.
if fromcall != notify_callsign:
return "{} was just seen by type:'{}'".format(fromcall, packet_type)
return f"{fromcall} was just seen by type:'{packet_type}'"
else:
LOG.debug(
"Not old enough to notify callsign '{}' : {} < {}".format(

View File

@ -3,6 +3,7 @@ import time
from aprsd import plugin, trace
LOG = logging.getLogger("APRSD")

View File

@ -4,6 +4,7 @@ import re
from aprsd import messaging, plugin, trace
LOG = logging.getLogger("APRSD")

View File

@ -1,9 +1,11 @@
import logging
import re
from aprsd import plugin, trace
import yfinance as yf
from aprsd import plugin, trace
LOG = logging.getLogger("APRSD")
@ -30,7 +32,7 @@ class StockPlugin(plugin.APRSDMessagePluginBase):
reply = "No stock symbol"
return reply
LOG.info("Fetch stock quote for '{}'".format(stock_symbol))
LOG.info(f"Fetch stock quote for '{stock_symbol}'")
try:
stock = yf.Ticker(stock_symbol)
@ -42,8 +44,8 @@ class StockPlugin(plugin.APRSDMessagePluginBase):
)
except Exception as e:
LOG.error(
"Failed to fetch stock '{}' from yahoo '{}'".format(stock_symbol, e),
f"Failed to fetch stock '{stock_symbol}' from yahoo '{e}'",
)
reply = "Failed to fetch stock '{}'".format(stock_symbol)
reply = f"Failed to fetch stock '{stock_symbol}'"
return reply.rstrip()

View File

@ -2,10 +2,12 @@ import logging
import re
import time
from aprsd import fuzzyclock, plugin, plugin_utils, trace, utils
from opencage.geocoder import OpenCageGeocode
import pytz
from aprsd import fuzzyclock, plugin, plugin_utils, trace, utils
LOG = logging.getLogger("APRSD")
@ -64,7 +66,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
@ -81,7 +83,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch location"
# LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
@ -95,7 +97,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
try:
utils.check_config_option(self.config, "opencagedata", "apiKey")
except Exception as ex:
LOG.error("Failed to find config opencage:apiKey {}".format(ex))
LOG.error(f"Failed to find config opencage:apiKey {ex}")
return "No opencage apiKey found"
try:
@ -103,7 +105,7 @@ class TimeOpenCageDataPlugin(TimePlugin):
geocoder = OpenCageGeocode(opencage_key)
results = geocoder.reverse_geocode(lat, lon)
except Exception as ex:
LOG.error("Couldn't fetch opencagedata api '{}'".format(ex))
LOG.error(f"Couldn't fetch opencagedata api '{ex}'")
# Default to UTC instead
localzone = pytz.timezone("UTC")
else:
@ -130,7 +132,7 @@ class TimeOWMPlugin(TimePlugin):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
# optional second argument is a callsign to search
@ -146,10 +148,10 @@ class TimeOWMPlugin(TimePlugin):
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch 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"
@ -163,14 +165,14 @@ class TimeOWMPlugin(TimePlugin):
["services", "openweathermap", "apiKey"],
)
except Exception as ex:
LOG.error("Failed to find config openweathermap:apiKey {}".format(ex))
LOG.error(f"Failed to find config openweathermap:apiKey {ex}")
return "No openweathermap apiKey found"
api_key = self.config["services"]["openweathermap"]["apiKey"]
try:
results = plugin_utils.fetch_openweathermap(api_key, lat, lon)
except Exception as ex:
LOG.error("Couldn't fetch openweathermap api '{}'".format(ex))
LOG.error(f"Couldn't fetch openweathermap api '{ex}'")
# default to UTC
localzone = pytz.timezone("UTC")
else:

View File

@ -3,6 +3,7 @@ import logging
import aprsd
from aprsd import plugin, stats, trace
LOG = logging.getLogger("APRSD")

View File

@ -2,9 +2,11 @@ import json
import logging
import re
from aprsd import plugin, plugin_utils, trace, utils
import requests
from aprsd import plugin, plugin_utils, trace, utils
LOG = logging.getLogger("APRSD")
@ -34,14 +36,14 @@ class USWeatherPlugin(plugin.APRSDMessagePluginBase):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, fromcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch location"
# LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
@ -51,7 +53,7 @@ class USWeatherPlugin(plugin.APRSDMessagePluginBase):
try:
wx_data = plugin_utils.get_weather_gov_for_gps(lat, lon)
except Exception as ex:
LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(ex))
LOG.error(f"Couldn't fetch forecast.weather.gov '{ex}'")
return "Unable to get weather"
reply = (
@ -65,7 +67,7 @@ class USWeatherPlugin(plugin.APRSDMessagePluginBase):
wx_data["data"]["weather"][1],
)
).rstrip()
LOG.debug("reply: '{}' ".format(reply))
LOG.debug(f"reply: '{reply}' ")
return reply
@ -93,7 +95,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
fromcall = packet.get("from")
message = packet.get("message_text", None)
# ack = packet.get("msgNo", "0")
LOG.info("WX Plugin '{}'".format(message))
LOG.info(f"WX Plugin '{message}'")
a = re.search(r"^.*\s+(.*)", message)
if a is not None:
searchcall = a.group(1)
@ -101,7 +103,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
try:
resp = plugin_utils.get_weather_gov_metar(station)
except Exception as e:
LOG.debug("Weather failed with: {}".format(str(e)))
LOG.debug(f"Weather failed with: {str(e)}")
reply = "Unable to find station METAR"
else:
station_data = json.loads(resp.text)
@ -118,7 +120,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
["services", "aprs.fi", "apiKey"],
)
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
@ -126,7 +128,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, fromcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch location"
# LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
@ -140,7 +142,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
try:
wx_data = plugin_utils.get_weather_gov_for_gps(lat, lon)
except Exception as ex:
LOG.error("Couldn't fetch forecast.weather.gov '{}'".format(ex))
LOG.error(f"Couldn't fetch forecast.weather.gov '{ex}'")
return "Unable to metar find station."
if wx_data["location"]["metar"]:
@ -148,7 +150,7 @@ class USMetarPlugin(plugin.APRSDMessagePluginBase):
try:
resp = plugin_utils.get_weather_gov_metar(station)
except Exception as e:
LOG.debug("Weather failed with: {}".format(str(e)))
LOG.debug(f"Weather failed with: {str(e)}")
reply = "Failed to get Metar"
else:
station_data = json.loads(resp.text)
@ -188,7 +190,7 @@ class OWMWeatherPlugin(plugin.APRSDMessagePluginBase):
fromcall = packet.get("from")
message = packet.get("message_text", None)
# ack = packet.get("msgNo", "0")
LOG.info("OWMWeather Plugin '{}'".format(message))
LOG.info(f"OWMWeather Plugin '{message}'")
a = re.search(r"^.*\s+(.*)", message)
if a is not None:
searchcall = a.group(1)
@ -199,14 +201,14 @@ class OWMWeatherPlugin(plugin.APRSDMessagePluginBase):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch location"
# LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
@ -223,7 +225,7 @@ class OWMWeatherPlugin(plugin.APRSDMessagePluginBase):
["services", "openweathermap", "apiKey"],
)
except Exception as ex:
LOG.error("Failed to find config openweathermap:apiKey {}".format(ex))
LOG.error(f"Failed to find config openweathermap:apiKey {ex}")
return "No openweathermap apiKey found"
try:
@ -244,7 +246,7 @@ class OWMWeatherPlugin(plugin.APRSDMessagePluginBase):
exclude="minutely,hourly",
)
except Exception as ex:
LOG.error("Couldn't fetch openweathermap api '{}'".format(ex))
LOG.error(f"Couldn't fetch openweathermap api '{ex}'")
# default to UTC
return "Unable to get weather"
@ -312,7 +314,7 @@ class AVWXWeatherPlugin(plugin.APRSDMessagePluginBase):
fromcall = packet.get("from")
message = packet.get("message_text", None)
# ack = packet.get("msgNo", "0")
LOG.info("OWMWeather Plugin '{}'".format(message))
LOG.info(f"OWMWeather Plugin '{message}'")
a = re.search(r"^.*\s+(.*)", message)
if a is not None:
searchcall = a.group(1)
@ -323,14 +325,14 @@ class AVWXWeatherPlugin(plugin.APRSDMessagePluginBase):
try:
utils.check_config_option(self.config, ["services", "aprs.fi", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config aprs.fi:apikey {}".format(ex))
LOG.error(f"Failed to find config aprs.fi:apikey {ex}")
return "No aprs.fi apikey found"
api_key = self.config["services"]["aprs.fi"]["apiKey"]
try:
aprs_data = plugin_utils.get_aprs_fi(api_key, searchcall)
except Exception as ex:
LOG.error("Failed to fetch aprs.fi data {}".format(ex))
LOG.error(f"Failed to fetch aprs.fi data {ex}")
return "Failed to fetch location"
# LOG.debug("LocationPlugin: aprs_data = {}".format(aprs_data))
@ -344,32 +346,32 @@ class AVWXWeatherPlugin(plugin.APRSDMessagePluginBase):
try:
utils.check_config_option(self.config, ["services", "avwx", "apiKey"])
except Exception as ex:
LOG.error("Failed to find config avwx:apiKey {}".format(ex))
LOG.error(f"Failed to find config avwx:apiKey {ex}")
return "No avwx apiKey found"
try:
utils.check_config_option(self.config, ["services", "avwx", "base_url"])
except Exception as ex:
LOG.debug("Didn't find avwx:base_url {}".format(ex))
LOG.debug(f"Didn't find avwx:base_url {ex}")
base_url = "https://avwx.rest"
else:
base_url = self.config["services"]["avwx"]["base_url"]
api_key = self.config["services"]["avwx"]["apiKey"]
token = "TOKEN {}".format(api_key)
token = f"TOKEN {api_key}"
headers = {"Authorization": token}
try:
coord = "{},{}".format(lat, lon)
coord = f"{lat},{lon}"
url = (
"{}/api/station/near/{}?"
"n=1&airport=false&reporting=true&format=json".format(base_url, coord)
)
LOG.debug("Get stations near me '{}'".format(url))
LOG.debug(f"Get stations near me '{url}'")
response = requests.get(url, headers=headers)
except Exception as ex:
LOG.error(ex)
raise Exception("Failed to get the weather '{}'".format(ex))
raise Exception(f"Failed to get the weather '{ex}'")
else:
wx_data = json.loads(response.text)
@ -385,11 +387,11 @@ class AVWXWeatherPlugin(plugin.APRSDMessagePluginBase):
)
)
LOG.debug("Get METAR '{}'".format(url))
LOG.debug(f"Get METAR '{url}'")
response = requests.get(url, headers=headers)
except Exception as ex:
LOG.error(ex)
raise Exception("Failed to get metar {}".format(ex))
raise Exception(f"Failed to get metar {ex}")
else:
metar_data = json.loads(response.text)

View File

@ -5,6 +5,7 @@ import threading
import aprsd
from aprsd import packets, plugin, utils
LOG = logging.getLogger("APRSD")

View File

@ -6,9 +6,11 @@ import threading
import time
import tracemalloc
from aprsd import client, messaging, packets, plugin, stats, utils
import aprslib
from aprsd import client, messaging, packets, plugin, stats, utils
LOG = logging.getLogger("APRSD")
RX_THREAD = "RX"
@ -214,7 +216,7 @@ class APRSDRXThread(APRSDThread):
def process_ack_packet(self, packet):
ack_num = packet.get("msgNo")
LOG.info("Got ack for message {}".format(ack_num))
LOG.info(f"Got ack for message {ack_num}")
messaging.log_message(
"ACK",
packet["raw"],
@ -257,7 +259,7 @@ class APRSDRXThread(APRSDThread):
# one of the plugins wants to send multiple messages
found_command = True
for subreply in reply:
LOG.debug("Sending '{}'".format(subreply))
LOG.debug(f"Sending '{subreply}'")
msg = messaging.TextMessage(
self.config["aprs"]["login"],
@ -272,7 +274,7 @@ class APRSDRXThread(APRSDThread):
# 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 messaging.NULL_MESSAGE:
LOG.debug("Sending '{}'".format(reply))
LOG.debug(f"Sending '{reply}'")
msg = messaging.TextMessage(
self.config["aprs"]["login"],

View File

@ -5,6 +5,7 @@ import logging
import time
import types
VALID_TRACE_FLAGS = {"method", "api"}
TRACE_API = False
TRACE_METHOD = False
@ -155,8 +156,6 @@ class TraceWrapperMetaclass(type):
class TraceWrapperWithABCMetaclass(abc.ABCMeta, TraceWrapperMetaclass):
"""Metaclass that wraps all methods of a class with trace."""
pass
def setup_tracing(trace_flags):
"""Set global variables for each trace flag.

View File

@ -10,12 +10,14 @@ import re
import sys
import threading
import aprsd
from aprsd import plugin
import click
import update_checker
import yaml
import aprsd
from aprsd import plugin
LOG_LEVELS = {
"CRITICAL": logging.CRITICAL,
"ERROR": logging.ERROR,
@ -102,9 +104,9 @@ DEFAULT_CONFIG_DICT = {
}
home = str(Path.home())
DEFAULT_CONFIG_DIR = "{}/.config/aprsd/".format(home)
DEFAULT_SAVE_FILE = "{}/.config/aprsd/aprsd.p".format(home)
DEFAULT_CONFIG_FILE = "{}/.config/aprsd/aprsd.yml".format(home)
DEFAULT_CONFIG_DIR = f"{home}/.config/aprsd/"
DEFAULT_SAVE_FILE = f"{home}/.config/aprsd/aprsd.p"
DEFAULT_CONFIG_FILE = f"{home}/.config/aprsd/aprsd.yml"
def synchronized(wrapped):
@ -229,7 +231,7 @@ def create_default_config():
config_file_expanded = os.path.expanduser(DEFAULT_CONFIG_FILE)
config_dir = os.path.dirname(config_file_expanded)
if not os.path.exists(config_dir):
click.echo("Config dir '{}' doesn't exist, creating.".format(config_dir))
click.echo(f"Config dir '{config_dir}' doesn't exist, creating.")
mkdir_p(config_dir)
with open(config_file_expanded, "w+") as cf:
cf.write(dump_default_cfg())
@ -245,7 +247,7 @@ def get_config(config_file):
else:
if config_file == DEFAULT_CONFIG_FILE:
click.echo(
"{} is missing, creating config file".format(config_file_expanded),
f"{config_file_expanded} is missing, creating config file",
)
create_default_config()
msg = (
@ -256,7 +258,7 @@ def get_config(config_file):
else:
# The user provided a config file path different from the
# Default, so we won't try and create it, just bitch and bail.
msg = "Custom config file '{}' is missing.".format(config_file)
msg = f"Custom config file '{config_file}' is missing."
click.echo(msg)
sys.exit(-1)

View File

@ -1,4 +1,3 @@
black
flake8
isort
mypy
@ -10,3 +9,4 @@ tox
twine
pre-commit
pip-tools
gray

View File

@ -4,6 +4,8 @@
#
# pip-compile dev-requirements.in
#
add-trailing-comma==2.1.0
# via gray
alabaster==0.7.12
# via sphinx
appdirs==1.4.4
@ -11,17 +13,19 @@ appdirs==1.4.4
# black
# virtualenv
attrs==20.3.0
# via pytest
# via
# jsonschema
# pytest
autoflake==1.4
# via gray
babel==2.9.1
# via sphinx
black==21.4b2
# via -r dev-requirements.in
black==21.7b0
# via gray
bleach==3.3.0
# via readme-renderer
certifi==2020.12.5
# via requests
cffi==1.14.5
# via cryptography
cfgv==3.2.0
# via pre-commit
chardet==4.0.0
@ -32,26 +36,35 @@ click==7.1.2
# pip-tools
colorama==0.4.4
# via twine
colorlog==6.4.1
# via prettylog
configargparse==1.5.2
# via gray
coverage==5.5
# via pytest-cov
cryptography==3.4.7
# via secretstorage
distlib==0.3.1
# via virtualenv
docutils==0.16
# via
# readme-renderer
# sphinx
fast-json==0.3.2
# via prettylog
filelock==3.0.12
# via
# tox
# virtualenv
fixit==0.1.4
# via gray
flake8-polyfill==1.0.2
# via pep8-naming
flake8==3.9.1
# via
# -r dev-requirements.in
# fixit
# flake8-polyfill
gray==0.10.1
# via -r dev-requirements.in
identify==2.2.4
# via pre-commit
idna==2.10
@ -62,18 +75,22 @@ importlib-metadata==4.0.1
# via
# keyring
# twine
importlib-resources==5.2.2
# via fixit
iniconfig==1.1.1
# via pytest
isort==5.8.0
# via -r dev-requirements.in
jeepney==0.6.0
# via
# keyring
# secretstorage
# -r dev-requirements.in
# gray
jinja2==2.11.3
# via sphinx
jsonschema==3.2.0
# via fixit
keyring==23.0.1
# via twine
libcst==0.3.20
# via fixit
markupsafe==1.1.1
# via jinja2
mccabe==0.6.1
@ -82,6 +99,7 @@ mypy-extensions==0.4.3
# via
# black
# mypy
# typing-inspect
mypy==0.812
# via -r dev-requirements.in
nodeenv==1.6.0
@ -108,22 +126,26 @@ pluggy==0.13.1
# tox
pre-commit==2.12.1
# via -r dev-requirements.in
prettylog==0.3.0
# via gray
py==1.10.0
# via
# pytest
# tox
pycodestyle==2.7.0
# via flake8
pycparser==2.20
# via cffi
pyflakes==2.3.1
# via flake8
# via
# autoflake
# flake8
pygments==2.9.0
# via
# readme-renderer
# sphinx
pyparsing==2.4.7
# via packaging
pyrsistent==0.18.0
# via jsonschema
pytest-cov==2.11.1
# via -r dev-requirements.in
pytest==6.2.3
@ -132,8 +154,13 @@ pytest==6.2.3
# pytest-cov
pytz==2021.1
# via babel
pyupgrade==2.24.0
# via gray
pyyaml==5.4.1
# via pre-commit
# via
# fixit
# libcst
# pre-commit
readme-renderer==29.0
# via twine
regex==2021.4.4
@ -147,11 +174,10 @@ requests==2.25.1
# twine
rfc3986==1.4.0
# via twine
secretstorage==3.3.1
# via keyring
six==1.15.0
# via
# bleach
# jsonschema
# readme-renderer
# tox
# virtualenv
@ -171,13 +197,18 @@ sphinxcontrib-qthelp==1.0.3
# via sphinx
sphinxcontrib-serializinghtml==1.1.4
# via sphinx
tokenize-rt==4.1.0
# via
# add-trailing-comma
# pyupgrade
toml==0.10.2
# via
# black
# pep517
# pre-commit
# pytest
# tox
tomli==1.2.1
# via black
tox==3.23.0
# via -r dev-requirements.in
tqdm==4.60.0
@ -187,7 +218,18 @@ twine==3.4.1
typed-ast==1.4.3
# via mypy
typing-extensions==3.10.0.0
# via mypy
# via
# libcst
# mypy
# typing-inspect
typing-inspect==0.7.1
# via libcst
ujson==4.1.0
# via fast-json
unify==0.5
# via gray
untokenize==0.1.1
# via unify
urllib3==1.26.5
# via requests
virtualenv==20.4.4
@ -197,7 +239,9 @@ virtualenv==20.4.4
webencodings==0.5.1
# via bleach
zipp==3.4.1
# via importlib-metadata
# via
# importlib-metadata
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
# pip

View File

@ -14,6 +14,7 @@
import os
import sys
sys.path.insert(0, os.path.abspath("../src"))

View File

@ -2,6 +2,7 @@ import logging
from aprsd import plugin
LOG = logging.getLogger("APRSD")
@ -15,5 +16,5 @@ class HelloPlugin(plugin.APRSDPluginBase):
def command(self, fromcall, message, ack):
LOG.info("HelloPlugin")
reply = "Hello '{}'".format(fromcall)
reply = f"Hello '{fromcall}'"
return reply

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

View File

@ -2,32 +2,12 @@
requires = ["setuptools>=46.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.black]
# Use the more relaxed max line length permitted in PEP8.
line-length = 88
target-version = ["py36", "py37", "py38"]
# black will automatically exclude all files listed in .gitignore
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
'''
[tool.isort]
profile = "black"
line_length = 88
force_sort_within_sections = true
multi_line_output = 4
line_length = 88
# Inform isort of paths to import names that should be considered part of the "First Party" group.
src_paths = ["src/openstack_loadtest"]
#src_paths = ["src/openstack_loadtest"]
skip_gitignore = true
# If you need to skip/exclude folders, consider using skip_glob as that will allow the
# isort defaults for skip to remain without the need to duplicate them.

View File

@ -16,6 +16,7 @@
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
import setuptools
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215

View File

@ -7,7 +7,7 @@ class TestEmail(unittest.TestCase):
def test_get_email_from_shortcut(self):
email.CONFIG = {"aprsd": {"email": {"shortcuts": {}}}}
email_address = "something@something.com"
addr = "-{}".format(email_address)
addr = f"-{email_address}"
actual = email.get_email_from_shortcut(addr)
self.assertEqual(addr, actual)

View File

@ -3,6 +3,7 @@ import unittest
from aprsd import email
if sys.version_info >= (3, 2):
from unittest import mock
else:

View File

@ -1,6 +1,8 @@
import unittest
from unittest import mock
import pytz
import aprsd
from aprsd import messaging, stats, utils
from aprsd.fuzzyclock import fuzzy
@ -9,7 +11,6 @@ from aprsd.plugins import ping as ping_plugin
from aprsd.plugins import query as query_plugin
from aprsd.plugins import time as time_plugin
from aprsd.plugins import version as version_plugin
import pytz
class TestPlugin(unittest.TestCase):
@ -171,7 +172,7 @@ class TestPlugin(unittest.TestCase):
@mock.patch("aprsd.plugin.PluginManager.get_msg_plugins")
def test_version(self, mock_get_plugins):
expected = "APRSD ver:{} uptime:0:0:0".format(aprsd.__version__)
expected = f"APRSD ver:{aprsd.__version__} uptime:0:0:0"
version = version_plugin.VersionPlugin(self.config)
packet = self.fake_packet(

20
tox.ini
View File

@ -76,9 +76,9 @@ exclude = .venv,.git,.tox,dist,doc,.ropeproject
# This section is not needed if not using GitHub Actions for CI.
[gh-actions]
python =
3.6: py36, pep8, fmt-check
3.7: py38, pep8, fmt-check
3.8: py38, pep8, fmt-check, type-check, docs
3.6: py36, pep8
3.7: py38, pep8
3.8: py38, pep8, type-check, docs
3.9: py39
[testenv:fmt]
@ -88,19 +88,7 @@ skip_install = true
deps =
-r{toxinidir}/dev-requirements.txt
commands =
isort .
black .
[testenv:fmt-check]
# Runs a check only on code formatting.
# you can fix imports by running isort standalone
# you can fix code formatting by running black standalone
skip_install = true
deps =
-r{toxinidir}/dev-requirements.txt
commands =
isort --check-only .
black --check .
gray aprsd tests
[testenv:type-check]
skip_install = true