2023-07-22 03:50:13 +03:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
import asyncio
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import irc.client
|
|
|
|
import irc.client_aio
|
|
|
|
|
|
|
|
from ax253 import Frame
|
2023-07-22 19:46:06 +03:00
|
|
|
from datetime import datetime
|
2023-07-22 03:50:13 +03:00
|
|
|
import kiss
|
2023-07-22 04:00:50 +03:00
|
|
|
import aprslib
|
2023-07-22 03:50:13 +03:00
|
|
|
|
2023-07-24 01:31:23 +03:00
|
|
|
import pick_pretty_description from aprs_to_callsign
|
|
|
|
|
2023-07-22 03:50:13 +03:00
|
|
|
MYCALL = os.environ.get("MYCALL", "N0CALL")
|
|
|
|
KISS_HOST = os.environ.get("KISS_HOST", "10.10.10.91")
|
|
|
|
KISS_PORT = os.environ.get("KISS_PORT", "8001")
|
|
|
|
|
|
|
|
server = os.environ.get('IRC_HOST', "irc.dead.guru")
|
|
|
|
port = int(os.environ.get('IRC_PORT', 6697))
|
|
|
|
channel = os.environ.get('CHANNEL_NAME', "#spau")
|
|
|
|
nickname = os.environ.get('BOT_NICK', "aprsbot")
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2023-07-22 04:00:50 +03:00
|
|
|
logging.basicConfig(level=logging.DEBUG) ## TODO: Make logging level configurable
|
2023-07-22 03:50:13 +03:00
|
|
|
|
2023-07-22 19:46:06 +03:00
|
|
|
def parse_frame(date, frame):
|
|
|
|
try:
|
|
|
|
parsed = aprslib.parse(str(frame))
|
|
|
|
except (aprslib.ParseError, aprslib.UnknownFormat) as exp:
|
|
|
|
logger.error(f"Failed to parse frame: {frame}")
|
|
|
|
return str(frame)
|
2023-07-24 01:31:23 +03:00
|
|
|
formatted_string = date.strftime('%H:%M:%S.%f')[:-3] + " " + "{} -> {} -> {}:".format(parsed["from"], parsed["via"], pick_pretty_description(parsed["to"])))
|
2023-07-22 19:46:06 +03:00
|
|
|
formatted_string += " <{:.4f} {:.4f}>".format(parsed["latitude"], parsed["longitude"]) if "longitude" in parsed and "latitude" in parsed else ""
|
|
|
|
formatted_string += " tUNIT: " + ",".join(parsed["tUNIT"]) if "tUNIT" in parsed else ""
|
|
|
|
formatted_string += " tPARM: " + ",".join(parsed["tPARM"]) if "tPARM" in parsed else ""
|
|
|
|
formatted_string += " tEQNS: " + ",".join([''.join(str(i)) for i in parsed["tEQNS"]]) if "tEQNS" in parsed else ""
|
|
|
|
formatted_string += " tBITS: {}".format(parsed["tBITS"]) if "tBITS" in parsed else ""
|
|
|
|
formatted_string += " {}".format(parsed["comment"]) if "comment" in parsed else ""
|
|
|
|
formatted_string += " {}".format(parsed["title"]) if "title" in parsed else ""
|
|
|
|
return formatted_string
|
|
|
|
|
2023-07-22 03:50:13 +03:00
|
|
|
async def main():
|
2023-07-22 03:53:20 +03:00
|
|
|
logger.info(f"Connecting to {server}:{port} as {nickname}")
|
2023-07-22 03:50:13 +03:00
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
|
2023-07-22 03:53:20 +03:00
|
|
|
irc_client = await irc.client_aio.AioReactor(loop=loop).server().connect(
|
|
|
|
server, port, nickname, connect_factory=irc.connection.AioFactory(ssl=True) ## TODO: Make SSL optional and add password support
|
2023-07-22 03:50:13 +03:00
|
|
|
)
|
2023-07-22 03:53:20 +03:00
|
|
|
logger.info(f"Connected to {server}:{port} as {nickname}")
|
2023-07-22 03:50:13 +03:00
|
|
|
|
|
|
|
transport, kiss_protocol = await kiss.create_tcp_connection(
|
|
|
|
host=KISS_HOST,
|
|
|
|
port=KISS_PORT,
|
|
|
|
loop=loop,
|
|
|
|
)
|
|
|
|
|
2023-07-22 19:46:06 +03:00
|
|
|
irc_client.privmsg(channel, 'Starting...')
|
2023-07-22 03:50:13 +03:00
|
|
|
|
|
|
|
async for frame in kiss_protocol.read():
|
2023-07-22 19:46:06 +03:00
|
|
|
time = datetime.utcnow()
|
|
|
|
|
2023-07-22 03:53:20 +03:00
|
|
|
logger.debug(f"Received frame: {frame}")
|
2023-07-22 19:46:06 +03:00
|
|
|
irc_client.privmsg(channel, parse_frame(time, frame))
|
2023-07-22 03:50:13 +03:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
asyncio.run(main())
|