Changeset - 7335282e5a64
[Not reviewed]
0 3 0
Brett Smith - 3 years ago 2021-03-11 18:52:31
brettcsmith@brettcsmith.org
rtutil: Add RTDateTime class.

See comments for rationale.
3 files changed with 58 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/rtutil.py
Show inline comments
...
 
@@ -6,4 +6,5 @@
 
# LICENSE.txt in the repository.
 

	
 
import datetime
 
import functools
 
import logging
...
 
@@ -14,4 +15,5 @@ import sqlite3
 
import urllib.parse as urlparse
 

	
 
import dateutil.parser
 
import rt
 

	
...
 
@@ -22,4 +24,5 @@ from beancount.core import data as bc_data
 

	
 
from typing import (
 
    cast,
 
    overload,
 
    Callable,
...
 
@@ -41,4 +44,26 @@ _LinkCache = MutableMapping[TicketAttachmentIds, Optional[str]]
 
_URLLookup = Callable[..., Optional[str]]
 

	
 
class RTDateTime(datetime.datetime):
 
    """Construct datetime objects from strings returned by RT
 

	
 
    Typical usage looks like::
 

	
 
        ticket = rt_client.get_ticket(...)
 
        created = RTDateTime(ticket.get('Created'))
 
    """
 
    # Normally I'd just write a function to do this, but having a dedicated
 
    # class helps support query-report: the class can pull double duty to both
 
    # parse the data from RT, and determine proper output formatting.
 
    # The RT REST API returns datetimes in the user's configured timezone, and
 
    # there doesn't seem to be any API call that tells you what that is. You
 
    # have to live with the object being timezone-naive.
 
    def __new__(cls, source: str) -> 'RTDateTime':
 
        if not source or source == 'Not set':
 
            retval = datetime.datetime.min
 
        else:
 
            retval = dateutil.parser.parse(source)
 
        return cast(RTDateTime, retval)
 

	
 

	
 
class RTLinkCache(_LinkCache):
 
    """Cache RT links to disk
setup.py
Show inline comments
...
 
@@ -18,4 +18,5 @@ setup(
 
        'odfpy>=1.4.0,!=1.4.1',  # Debian:python3-odf
 
        'pdfminer.six>=20200101',
 
        'python-dateutil>=2.7',  # Debian:python3-dateutil
 
        'PyYAML>=3.0',  # Debian:python3-yaml
 
        'regex',  # Debian:python3-regex
tests/test_rtutil.py
Show inline comments
...
 
@@ -7,4 +7,5 @@
 

	
 
import contextlib
 
import datetime
 
import itertools
 
import logging
...
 
@@ -288,2 +289,33 @@ def test_txn_with_urls_with_fmts(rt):
 
        '[stmt.txt]',
 
    ])
 

	
 
@pytest.mark.parametrize('arg,exp_num,exp_offset', [
 
    # These correspond to the different datetime formats available through
 
    # RT's user settings.
 
    ('Mon Mar 1 01:01:01 2021', 1, None),
 
    ('2021-03-02 02:02:02', 2, None),
 
    ('2021-03-03T03:03:03-0500', 3, -18000),
 
    ('Thu, 4 Mar 2021 04:04:04 -0600', 4, -21600),
 
    ('Fri, 5 Mar 2021 05:05:05 GMT', 5, 0),
 
    ('20210306T060606Z', 6, 0),
 
    ('Sun, Mar 7, 2021 07:07:07 AM', 7, None),
 
    ('Sun, Mar 14, 2021 02:14:14 PM', 14, None),
 
])
 
def test_rt_datetime(arg, exp_num, exp_offset):
 
    actual = rtutil.RTDateTime(arg)
 
    assert actual.year == 2021
 
    assert actual.month == 3
 
    assert actual.day == exp_num
 
    assert actual.hour == exp_num
 
    assert actual.minute == exp_num
 
    assert actual.second == exp_num
 
    if exp_offset is None:
 
        assert actual.tzinfo is None
 
    else:
 
        assert actual.tzinfo.utcoffset(None).total_seconds() == exp_offset
 

	
 
@pytest.mark.parametrize('arg', ['Not set', '', None])
 
def test_rt_datetime_empty(arg):
 
    actual = rtutil.RTDateTime(arg)
 
    assert actual == datetime.datetime.min
 
    assert actual.tzinfo is None
0 comments (0 inline, 0 general)