Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions apprise/utils/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,18 @@
re.I,
)

# A simple verification check to make sure the content specified
# rougly conforms to a ham radio call sign before we parse it further
# Quick sanity check - does this look like a valid callsign before we
# bother parsing it
IS_CALL_SIGN = re.compile(
r"^(?P<callsign>[a-z0-9]{2,3}[0-9][a-z0-9]{3})"
r"(?P<ssid>-[a-z0-9]{1,2})?\s*$",
r"^(?P<callsign>[a-z]{1,3}[0-9][a-z]{1,3})"
r"(?P<ssid>-(?:[0-9]|1[0-5]))?\s*$",
re.I,
)

# Regular expression used to destinguish between multiple ham radio call signs
# Regex to split multiple callsigns from a single string
CALL_SIGN_DETECTION_RE = re.compile(
r"\s*([a-z0-9]{2,3}[0-9][a-z0-9]{3}(?:-[a-z0-9]{1,2})?)"
r"(?=$|[\s,]+[a-z0-9]{4,6})",
r"\s*([a-z0-9]{1,2}[0-9][a-z0-9]{1,3}(?:-(?:[0-9]|1[0-5]))?)"
r"(?=\s*$|\s*[,;\s]+)",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "look ahead" should also include the prefix for the next potential match, not just the delimiter to get to it (see how it was before). It's just a subtle change needed here I think. The real issue may have been that the value before was correct, but there were no test cases to back it up? Your current solution may be okay (if provided multiple inputs)?

Do the following work:

  • CSVAR, CSVAR2,,,,
  • CSVAR, CSVAR2-CID, CSVAR3-CID, CSVAR4,,,,
  • CSVAR, CSVAR2
  • CSVAR, INVALIDCS;,,, CSVAR2,,,,

Where CSVAR should be valid variations of callsigns (including the new shortened version you introduced)?

I think if the look-ahead in the prefix doesn't also include the validity of the next item too, you'll generate successfully on blank matches in situations where the input ends with a delimiter?

I want to be clear; i don't know that it's also possible what you have is okay too; I hadn't had a chance to look closer at it.

Thoughts? Does this safely cover this? I didn't see any added tests in tests/test_apprise_utils.py to test parse_call_sign()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I went down this path at all is that my own call: N1HAN, is invalid according to the existing regex. I'll take a closer look at this PR again with fresh eyes and see if anything different stands out. You've raised some good points I didn't consider in my initial pass.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neil-forks-apprise-callsign.patch

I had a chance to look at your code and fix it. I don't have permission to change your master branch, so here is the solution that should accomodate you and me at the same time. If you want to apply it to this branch and resubmit, we should be good to go.

re.I,
)

Expand Down
26 changes: 25 additions & 1 deletion tests/test_apprise_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1685,14 +1685,38 @@ def test_is_call_sign_no():
assert utils.parse.is_call_sign(42) is False

# To short or 2 long
assert utils.parse.is_call_sign("DF1AB") is False
assert utils.parse.is_call_sign("DF1ABCX") is False
assert utils.parse.is_call_sign("DF1ABCEFG") is False
assert utils.parse.is_call_sign("1ABCX") is False
# 4th character is not an number
assert utils.parse.is_call_sign("XXXXXX") is False

# Some valid checks
# 1x2
result = utils.parse.is_call_sign("A0AF")
assert isinstance(result, dict)
assert result["callsign"] == "A0AF"
assert result["ssid"] == ""

# 2x1
result = utils.parse.is_call_sign("AA0A")
assert isinstance(result, dict)
assert result["callsign"] == "AA0A"
assert result["ssid"] == ""

# 2x2
result = utils.parse.is_call_sign("AA0AF")
assert isinstance(result, dict)
assert result["callsign"] == "AA0AF"
assert result["ssid"] == ""

# 1x3
result = utils.parse.is_call_sign("K0ACL")
assert isinstance(result, dict)
assert result["callsign"] == "K0ACL"
assert result["ssid"] == ""

# 2x3
result = utils.parse.is_call_sign("DF1ABC")
assert isinstance(result, dict)
assert result["callsign"] == "DF1ABC"
Expand Down
6 changes: 6 additions & 0 deletions tests/test_plugin_aprs.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ def test_plugin_aprs_urls(mock_create_connection):
)
assert instance.notify("test") is True

# 1N3 callsigns
instance = apprise.Apprise.instantiate(
"aprs://D1JSL-15:12345@D1ABC"
)
assert isinstance(instance, NotifyAprs)

instance = apprise.Apprise.instantiate(
"aprs://DF1JSL-15:12345@DF1ABC?delay=3.0"
)
Expand Down
Loading