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 functools
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
import re
|
||||||
import urllib.parse as urlparse
|
import urllib.parse as urlparse
|
||||||
|
|
||||||
import rt
|
import rt
|
||||||
|
@ -31,6 +32,11 @@ AttachmentTuple = Tuple[str, str, str, str]
|
||||||
RTId = Union[int, str]
|
RTId = Union[int, str]
|
||||||
|
|
||||||
class RT:
|
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:
|
def __init__(self, rt_client: rt.Rt) -> None:
|
||||||
self.rt = rt_client
|
self.rt = rt_client
|
||||||
urlparts = urlparse.urlparse(rt_client.url)
|
urlparts = urlparse.urlparse(rt_client.url)
|
||||||
|
@ -94,6 +100,14 @@ class RT:
|
||||||
def exists(self, ticket_id: RTId, attachment_id: Optional[RTId]=None) -> bool:
|
def exists(self, ticket_id: RTId, attachment_id: Optional[RTId]=None) -> bool:
|
||||||
return self.url(ticket_id, attachment_id) is not None
|
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()
|
@functools.lru_cache()
|
||||||
def ticket_url(self, ticket_id: RTId) -> Optional[str]:
|
def ticket_url(self, ticket_id: RTId) -> Optional[str]:
|
||||||
if self.rt.get_ticket(ticket_id) is None:
|
if self.rt.get_ticket(ticket_id) is None:
|
||||||
|
|
|
@ -35,7 +35,7 @@ EXPECTED_URLS = [
|
||||||
(9, None, None),
|
(9, None, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture(scope='module')
|
||||||
def rt():
|
def rt():
|
||||||
client = testutil.RTClient()
|
client = testutil.RTClient()
|
||||||
return rtutil.RT(client)
|
return rtutil.RT(client)
|
||||||
|
@ -97,3 +97,27 @@ def test_exists_caches(new_client):
|
||||||
assert rt.exists(2)
|
assert rt.exists(2)
|
||||||
assert not rt.exists(1, 9)
|
assert not rt.exists(1, 9)
|
||||||
assert not rt.exists(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