From 63736c24724cd003e88764c4eb09ea600881b405 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Thu, 30 Nov 2023 15:22:59 -0500 Subject: [PATCH] Add a tool for listening to RBN data --- scripts/rbn-grep | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100755 scripts/rbn-grep diff --git a/scripts/rbn-grep b/scripts/rbn-grep new file mode 100755 index 0000000..e349db9 --- /dev/null +++ b/scripts/rbn-grep @@ -0,0 +1,88 @@ +#! /usr/bin/env python3 +import argparse +import sys +import re +import socket + + +def main() -> int: + # Handle program arguments + ap = argparse.ArgumentParser( + prog="rbn-grep", description="Grep against RBN data in real-time" + ) + ap.add_argument( + "--callsign", "-c", help="REGEX for the TX-ing callsign", default=".*" + ) + ap.add_argument( + "--spotter", "-s", help="REGEX for the spotting callsign", default=".*" + ) + ap.add_argument( + "--min-frequency", "--fl", help="Minimum frequency in kc", type=float, default=0 + ) + ap.add_argument( + "--max-frequency", + "--fh", + help="Maximum frequency in kc", + type=float, + default=sys.maxsize, + ) + ap.add_argument( + "--stream-type", + "--st", + help="Stream type", + default="analog", + choices=["analog", "digital"], + ) + ap.add_argument("--login-callsign", help="Login callsign", default="n0call") + args = ap.parse_args() + + # Compile regexes + callsign_regex = re.compile(args.callsign, re.IGNORECASE) + spotter_regex = re.compile(args.spotter, re.IGNORECASE) + + # Connect to the RBN Telnet servers + conn = socket.create_connection( + ("telnet.reversebeacon.net", 7000 if args.stream_type == "analog" else 7001) + ) + + # Log in + conn.send(f"{args.login_callsign}\n".encode("ascii")) + + # Read lines and filter + try: + while True: + # Read a line + lines = conn.recv(1024).decode("ascii").strip() + for line in lines.splitlines(): + line_split = [x for x in line.split(" ") if x] + + # Ignore bad lines + if not line.startswith("DX"): + continue + + # Parse the data + spotter = line_split[2] + frequency_kc = float(line_split[3]) + spotted = line_split[4] + + # Filter + if ( + not callsign_regex.match(spotted) + or not spotter_regex.match(spotter) + or frequency_kc < args.min_frequency + or frequency_kc > args.max_frequency + ): + continue + + # Print the line + print(line) + + except KeyboardInterrupt: + print("\nGoodbye") + conn.close() + + return 0 + + +if __name__ == "__main__": + sys.exit(main())