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:
parent
d5a6141f6d
commit
9fbc658aa6
2 changed files with 39 additions and 1 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue