From 5ce9dec34ca2c38fc154afb19c036148f1e17de4 Mon Sep 17 00:00:00 2001 From: "Fabian P. Schmidt" Date: Sun, 15 Nov 2015 19:21:19 +0100 Subject: [PATCH] Add AprsParseError. --- ogn/aprs_parser.py | 16 ++++++++-------- ogn/exceptions.py | 12 ++++++++++++ ogn/gateway/__init__.py | 11 ++++++----- ogn/model/beacon.py | 11 ++++++----- 4 files changed, 32 insertions(+), 18 deletions(-) create mode 100644 ogn/exceptions.py diff --git a/ogn/aprs_parser.py b/ogn/aprs_parser.py index 3cdea88..7db6d47 100644 --- a/ogn/aprs_parser.py +++ b/ogn/aprs_parser.py @@ -1,16 +1,16 @@ from .model import Beacon, AircraftBeacon, ReceiverBeacon +from ogn.exceptions import AprsParseError - -def parse_aprs(text): - if not isinstance(text, str): - raise Exception("Unknown type: %s" % type(text)) - elif text == "": - raise Exception("String is empty") - elif text[0] == "#": +def parse_aprs(packet): + if not isinstance(packet, str): + raise TypeError("Expected packet to be str, got %s" % type(packet)) + elif packet == "": + raise AprsParseError(substring=packet, expected_type="non-empty aprs packet") + elif packet[0] == "#": return None beacon = Beacon() - beacon.parse(text) + beacon.parse(packet) # symboltable / symbolcodes used by OGN: # I&: used as receiver diff --git a/ogn/exceptions.py b/ogn/exceptions.py new file mode 100644 index 0000000..d4d8566 --- /dev/null +++ b/ogn/exceptions.py @@ -0,0 +1,12 @@ +""" +exception definitions +""" + + +class AprsParseError(Exception): + """Parse error while parsing an aprs packet substring.""" + def __init__(self, substring, expected_type): + self.message = "Aprs Substring can't be parsed as %s." % expected_type + super(AprsParseError, self).__init__(self.message) + self.substring = substring + self.expected_type = expected_type diff --git a/ogn/gateway/__init__.py b/ogn/gateway/__init__.py index 31a5eff..99a6e3b 100644 --- a/ogn/gateway/__init__.py +++ b/ogn/gateway/__init__.py @@ -4,6 +4,7 @@ from time import time from ogn.gateway import settings from ogn.commands.dbutils import session from ogn.aprs_parser import parse_aprs +from ogn.exceptions import AprsParseError from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker @@ -27,14 +28,14 @@ class ognGateway: self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.sock.connect((settings.APRS_SERVER_HOST, settings.APRS_SERVER_PORT)) - login = 'user %s pass %s vers ogn-gateway-python %s %s\n' % (aprs_user, settings.APRS_PASSCODE, MODULE_VERSION, settings.APRS_FILTER) + login = 'user %s pass %s vers ogn-gateway-python %s %s\n' % (aprs_user, settings.APRS_PASSCODE, MODULE_VERSION, settings.APRS_FILTER) self.sock.send(login.encode()) self.sock_file = self.sock.makefile('rw') def run(self): keepalive_time = time() while True: - if time()-keepalive_time > 60: + if time() - keepalive_time > 60: self.sock.send("#keepalive".encode()) keepalive_time = time() @@ -60,9 +61,9 @@ class ognGateway: def proceed_line(self, line): try: beacon = parse_aprs(line) - except Exception as e: - print('Failed to parse line: %s' % line) - print('Reason: %s' % e) + except AprsParseError as e: + print(e.message) + print("Substring: " % e.substring) return if beacon is not None: diff --git a/ogn/model/beacon.py b/ogn/model/beacon.py index 4d14955..511a383 100644 --- a/ogn/model/beacon.py +++ b/ogn/model/beacon.py @@ -4,12 +4,13 @@ from sqlalchemy import Column, String, Integer, Float, DateTime from sqlalchemy.ext.declarative import AbstractConcreteBase from ogn.aprs_utils import createTimestamp, dmsToDeg, kts2kmh, feet2m +from ogn.exceptions import AprsParseError from .base import Base # "original" pattern from OGN: "(.+?)>APRS,.+,(.+?):/(\\d{6})+h(\\d{4}\\.\\d{2})(N|S).(\\d{5}\\.\\d{2})(E|W).((\\d{3})/(\\d{3}))?/A=(\\d{6}).*?" PATTERN_APRS = r"^(.+?)>APRS,.+,(.+?):/(\d{6})+h(\d{4}\.\d{2})(N|S)(.)(\d{5}\.\d{2})(E|W)(.)((\d{3})/(\d{3}))?/A=(\d{6})\s(.*)$" -prog = re.compile(PATTERN_APRS) +re_pattern_aprs = re.compile(PATTERN_APRS) class Beacon(AbstractConcreteBase, Base): @@ -29,9 +30,9 @@ class Beacon(AbstractConcreteBase, Base): comment = None def parse(self, text, reference_time=None): - result = prog.match(text) + result = re_pattern_aprs.match(text) if result is None: - raise Exception("String is not valid" % text) + raise AprsParseError(substring=text, expected_type="Beacon") self.name = result.group(1) self.receiver_name = result.group(2) @@ -52,11 +53,11 @@ class Beacon(AbstractConcreteBase, Base): if result.group(10) is not None: self.track = int(result.group(11)) - self.ground_speed = int(result.group(12))*kts2kmh + self.ground_speed = int(result.group(12)) * kts2kmh else: self.track = 0 self.ground_speed = 0 - self.altitude = int(result.group(13))*feet2m + self.altitude = int(result.group(13)) * feet2m self.comment = result.group(14)