Catch exception while parsing the APRS comment (fixes #126)

master
Konstantin Gründger 2025-04-19 09:06:58 +02:00 zatwierdzone przez Meisterschueler
rodzic 1e20d187a1
commit ebe61f151b
3 zmienionych plików z 26 dodań i 15 usunięć

Wyświetl plik

@ -1,12 +1,17 @@
# CHANGELOG # CHANGELOG
## 1.2.3: - 2024-04-01 =======
- parser: Add Microtrak parser ## 1.3.0: - 2025-04-19
- parser: Handle messages that do not conform to the "ogn-aprs-protocol" specification/implementation (fixes #126)
- Moved dependency management to to poetry
- Added github action pipeline for automated testing and publishing
## 1.2.2: - 2024-03-31 ## 1.2.3: - 2024-04-01 (not released on PyPI)
- parser: Added support for OGNMTK (Microtrak) beacons
## 1.2.2: - 2024-03-31 (not released on PyPI)
- client: If no reference_timestamp provided use timestamp from APRS server (fixes #85) - client: If no reference_timestamp provided use timestamp from APRS server (fixes #85)
- parser: Handle dst_calls 'OGFLR6' (protocol 6) and 'OGFLR7' (protocol 7) like 'OGFLR' (fixes #123) - parser: Handle dst_calls 'OGFLR6' (protocol 6) and 'OGFLR7' (protocol 7) like 'OGFLR' (fixes #123)
- parser: Added support for OGNMTK (Microtrak) beacons
## 1.2.1: - 2021-06-06 ## 1.2.1: - 2021-06-06
- client: Added peer IP to log messages - client: Added peer IP to log messages

Wyświetl plik

@ -1,9 +1,8 @@
import re
from datetime import datetime from datetime import datetime
from ogn.parser.utils import createTimestamp, parseAngle, KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER, INCH_TO_MM, fahrenheit_to_celsius, CheapRuler, normalized_quality from ogn.parser.utils import createTimestamp, parseAngle, KNOTS_TO_MS, KPH_TO_MS, FEETS_TO_METER, INCH_TO_MM, fahrenheit_to_celsius, CheapRuler, normalized_quality
from ogn.parser.pattern import PATTERN_APRS, PATTERN_APRS_POSITION, PATTERN_APRS_POSITION_WEATHER, PATTERN_APRS_STATUS, PATTERN_SERVER from ogn.parser.pattern import PATTERN_APRS, PATTERN_APRS_POSITION, PATTERN_APRS_POSITION_WEATHER, PATTERN_APRS_STATUS, PATTERN_SERVER
from ogn.parser.exceptions import AprsParseError from ogn.parser.exceptions import AprsParseError, OgnParseError
from ogn.parser.aprs_comment.ogn_parser import OgnParser from ogn.parser.aprs_comment.ogn_parser import OgnParser
from ogn.parser.aprs_comment.fanet_parser import FanetParser from ogn.parser.aprs_comment.fanet_parser import FanetParser
@ -34,9 +33,12 @@ def parse(aprs_message, reference_timestamp=None, calculate_relations=False, use
message = parse_aprs(aprs_message, reference_timestamp=reference_timestamp) message = parse_aprs(aprs_message, reference_timestamp=reference_timestamp)
if message['aprs_type'] == 'position' or message['aprs_type'] == 'status': if message['aprs_type'] == 'position' or message['aprs_type'] == 'status':
message.update(parse_comment(message['comment'], try:
dstcall=message['dstcall'], message.update(parse_comment(message['comment'],
aprs_type=message['aprs_type'])) dstcall=message['dstcall'],
aprs_type=message['aprs_type']))
except Exception:
raise OgnParseError(f"dstcall: {message['dstcall']}, aprs_type: {message['aprs_type']}, comment: {message['comment']}")
if message['aprs_type'].startswith('position') and calculate_relations is True: if message['aprs_type'].startswith('position') and calculate_relations is True:
positions[message['name']] = (message['longitude'], message['latitude']) positions[message['name']] = (message['longitude'], message['latitude'])
@ -60,7 +62,7 @@ def parse_aprs(message, reference_timestamp=None):
'reference_timestamp': reference_timestamp} 'reference_timestamp': reference_timestamp}
if message and message[0] == '#': if message and message[0] == '#':
match_server = re.search(PATTERN_SERVER, message) match_server = PATTERN_SERVER.search(message)
if match_server: if match_server:
result.update({ result.update({
'version': match_server.group('version'), 'version': match_server.group('version'),
@ -74,13 +76,13 @@ def parse_aprs(message, reference_timestamp=None):
'comment': message, 'comment': message,
'aprs_type': 'comment'}) 'aprs_type': 'comment'})
else: else:
match = re.search(PATTERN_APRS, message) match = PATTERN_APRS.search(message)
if match: if match:
aprs_type = 'position' if match.group('aprs_type') == '/' else 'status' if match.group('aprs_type') == '>' else 'unknown' aprs_type = 'position' if match.group('aprs_type') == '/' else 'status' if match.group('aprs_type') == '>' else 'unknown'
result.update({'aprs_type': aprs_type}) result.update({'aprs_type': aprs_type})
aprs_body = match.group('aprs_body') aprs_body = match.group('aprs_body')
if aprs_type == 'position': if aprs_type == 'position':
match_position = re.search(PATTERN_APRS_POSITION, aprs_body) match_position = PATTERN_APRS_POSITION.search(aprs_body)
if match_position: if match_position:
result.update({ result.update({
'name': match.group('callsign'), 'name': match.group('callsign'),
@ -103,7 +105,7 @@ def parse_aprs(message, reference_timestamp=None):
}) })
return result return result
match_position_weather = re.search(PATTERN_APRS_POSITION_WEATHER, aprs_body) match_position_weather = PATTERN_APRS_POSITION_WEATHER.search(aprs_body)
if match_position_weather: if match_position_weather:
result.update({ result.update({
'aprs_type': 'position_weather', 'aprs_type': 'position_weather',
@ -135,7 +137,7 @@ def parse_aprs(message, reference_timestamp=None):
raise AprsParseError(message) raise AprsParseError(message)
elif aprs_type == 'status': elif aprs_type == 'status':
match_status = re.search(PATTERN_APRS_STATUS, aprs_body) match_status = PATTERN_APRS_STATUS.search(aprs_body)
if match_status: if match_status:
result.update({ result.update({
'name': match.group('callsign'), 'name': match.group('callsign'),

Wyświetl plik

@ -6,7 +6,7 @@ from datetime import datetime
from time import sleep from time import sleep
from ogn.parser.parse import parse from ogn.parser.parse import parse
from ogn.parser.exceptions import AprsParseError from ogn.parser.exceptions import AprsParseError, OgnParseError
class TestStringMethods(unittest.TestCase): class TestStringMethods(unittest.TestCase):
@ -114,6 +114,10 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(message['name'], 'FLRDDA5BA') self.assertEqual(message['name'], 'FLRDDA5BA')
self.assertEqual(message['address'], 'DDA5BA') self.assertEqual(message['address'], 'DDA5BA')
def test_bad_naviter_format(self):
with self.assertRaises(OgnParseError):
parse("FLRA51D93>OGNAVI,qAS,NAVITER2:/204507h4444.98N/09323.34W'000/000/A=000925 !W67! id06A51D93 +000fpm +0.0rot")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()