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…
	
	Add table
		
		Reference in a new issue