Last active
May 15, 2024 01:52
-
-
Save 0x9900/d8b8282c270f2a6910e1cc6e878553d5 to your computer and use it in GitHub Desktop.
Automatically send QSL cards by calling eqsl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# BSD 3-Clause License | |
# Copyright (c) 2023 Fred W6BSD All rights reserved. | |
# | |
""" | |
`sendcard` is a companion program for e-qsl (https://pypi.org/project/e-qsl/) | |
This program monitors a directory for an ADIF file and then calls `eqsl` | |
with the file as an argument. | |
""" | |
import logging | |
import os | |
import shutil | |
from argparse import ArgumentParser | |
from importlib.metadata import version | |
from pathlib import Path | |
from subprocess import call | |
from typing import Optional | |
from watchfiles import Change, DefaultFilter, watch | |
SHOW_CARD = False | |
logging.basicConfig( | |
format="%(asctime)s %(name)s:%(lineno)d %(levelname)s - %(message)s", | |
level=logging.INFO | |
) | |
wf_log = logging.getLogger('watchfiles.main') | |
wf_log.setLevel(logging.CRITICAL) | |
__version__ = version("e-qsl") | |
def send_cards(filename: Path, show_card: bool) -> None: | |
eqsl: Optional[str] = shutil.which('eqsl') | |
if not eqsl: | |
raise FileNotFoundError('eqsl not found') | |
args: list[str] = [eqsl, '-k', '-a', str(filename)] | |
if show_card: | |
args.append('-s') | |
logging.info('Command: %s', ' '.join(args)) | |
call(args) | |
class ADIFilter(DefaultFilter): | |
# pylint: disable=too-few-public-methods | |
def __init__(self, directory: str, name: str) -> None: | |
super().__init__() | |
self.full_name = os.path.join(directory, name) | |
def __call__(self, change: Change, path: str) -> bool: | |
return super().__call__(change, path) and path == self.full_name | |
def sendcard() -> None: | |
parser = ArgumentParser(description="Watch for the creation on an adif file and call eqsl") | |
parser.add_argument("-s", "--show", action="store_true", default=False, | |
help="Show the card") | |
parser.add_argument("-a", "--adif", required=True, | |
help="ADIF file name") | |
parser.add_argument("--version", action="version", version=f'eqsl.%(prog)s {__version__}') | |
opts = parser.parse_args() | |
full_name = Path(opts.adif).expanduser().absolute() | |
if full_name.exists(): | |
logging.info('The ADIF file already exists. Sending cards.') | |
try: | |
send_cards(full_name, opts.show) | |
except FileNotFoundError as err: | |
logging.debug(err) | |
path = full_name.parent | |
adif_file = full_name.parts[-1] | |
if not path.exists(): | |
raise FileNotFoundError(f'The directory {path} does not exist') | |
watch_filter = ADIFilter(path, adif_file) | |
logging.info('Sendcards watching %s for %s', path, adif_file) | |
for changes in watch(path, watch_filter=watch_filter, recursive=False): | |
for change, filename in changes: | |
if change in (Change.added, Change.modified): | |
send_cards(filename, opts.show) | |
def main(): | |
try: | |
sendcard() | |
except FileNotFoundError as err: | |
logging.info(err) | |
except KeyboardInterrupt: | |
logging.info('Exit "^C" pressed') | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment