rtutil: Add RT.parse method.

This method can parse the ticket and (optional) attachment IDs
out of our short-hand link formats, both for Ledger and Beancount.
This commit is contained in:
Brett Smith 2020-03-24 18:24:31 -04:00
parent d5a6141f6d
commit 9fbc658aa6
2 changed files with 39 additions and 1 deletions

View file

@ -16,6 +16,7 @@
import functools
import mimetypes
import re
import urllib.parse as urlparse
import rt
@ -31,6 +32,11 @@ AttachmentTuple = Tuple[str, str, str, str]
RTId = Union[int, str]
class RT:
PARSE_REGEXPS = [
re.compile(r'^rt:([0-9]+)(?:/([0-9]+))?/?$'),
re.compile(r'^rt://ticket/([0-9]+)(?:/attachments?/([0-9]+))?/?$'),
]
def __init__(self, rt_client: rt.Rt) -> None:
self.rt = rt_client
urlparts = urlparse.urlparse(rt_client.url)
@ -94,6 +100,14 @@ class RT:
def exists(self, ticket_id: RTId, attachment_id: Optional[RTId]=None) -> bool:
return self.url(ticket_id, attachment_id) is not None
def parse(self, s: str) -> Optional[Tuple[str, Optional[str]]]:
for regexp in self.PARSE_REGEXPS:
match = regexp.match(s)
if match is not None:
ticket_id, attachment_id = match.groups()
return (ticket_id, attachment_id)
return None
@functools.lru_cache()
def ticket_url(self, ticket_id: RTId) -> Optional[str]:
if self.rt.get_ticket(ticket_id) is None:

View file

@ -35,7 +35,7 @@ EXPECTED_URLS = [
(9, None, None),
]
@pytest.fixture
@pytest.fixture(scope='module')
def rt():
client = testutil.RTClient()
return rtutil.RT(client)
@ -97,3 +97,27 @@ def test_exists_caches(new_client):
assert rt.exists(2)
assert not rt.exists(1, 9)
assert not rt.exists(9)
@pytest.mark.parametrize('link,expected', [
('rt:1/2', ('1', '2')),
('rt:123/456', ('123', '456')),
('rt:12345', ('12345', None)),
('rt:12346/', ('12346', None)),
('rt:12346/789', ('12346', '789')),
('rt:12346/780/', ('12346', '780')),
('rt://ticket/1', ('1', None)),
('rt://ticket/1/', ('1', None)),
('rt://ticket/1234/attachments/5678', ('1234', '5678')),
('rt://ticket/1234/attachments/5678/', ('1234', '5678')),
('rt://ticket/1234/attachment/5678', ('1234', '5678')),
('rt://ticket/1234/attachment/5678/', ('1234', '5678')),
('rt:', None),
('rt://', None),
('rt:example.org', None),
('rt:example.org/1', None),
('rt://example.org', None),
('rt://example.org/1', None),
('https://example.org/rt/Ticket/Display.html?id=123', None),
])
def test_parse(rt, link, expected):
assert rt.parse(link) == expected