Skip to content

Commit

Permalink
Merge pull request #49 from lukasthaler/master
Browse files Browse the repository at this point in the history
Fixes #48
  • Loading branch information
omarryhan authored Feb 6, 2021
2 parents 8410dcf + f5814e0 commit 3fddf69
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 1 deletion.
9 changes: 8 additions & 1 deletion aiogoogle/auth/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import hashlib
import os
import datetime
import sys

from ..utils import _parse_isoformat


def create_secret(bytes_length=1024): # pragma: no cover
Expand All @@ -22,7 +25,11 @@ def _is_expired(expires_at):
if expires_at is None:
return True
if not isinstance(expires_at, datetime.datetime):
expires_at = datetime.datetime.fromisoformat(expires_at)
# datetime.fromisoformat is 3.7+
if sys.version_info[1] <= 6:
expires_at = _parse_isoformat(expires_at)
else:
expires_at = datetime.fromisoformat(expires_at)
if datetime.datetime.utcnow() >= expires_at:
return True
else:
Expand Down
59 changes: 59 additions & 0 deletions aiogoogle/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
__all__ = []

import datetime
import re


def _safe_getitem(dct, *keys):
for key in keys:
Expand Down Expand Up @@ -40,3 +43,59 @@ def __delattr__(self, item): # pragma: no cover
def __delitem__(self, key): # pragma: no cover
super(_dict, self).__delitem__(key)
del self.__dict__[key]


def _parse_time_components(tstr):
# supported format is HH[:MM[:SS[.fff[fff]]]]
if len(tstr) < 2:
raise ValueError("Invalid Isotime format")
hh = tstr[:2]
mm_ss = re.findall(r":(\d{2})", tstr)
ff = re.findall(r"\.(\d+)", tstr)
if ff and not len(ff[0]) in [3, 6]:
raise ValueError("Invalid Isotime format")
ff = ff[0] if ff else []

# ensure tstr was valid
if len(mm_ss) < 2 and ff:
raise ValueError("Invalid Isotime format")
parsed_str = hh + (":" + ":".join(mm_ss) if mm_ss else "") + \
("." + ff if ff else "")
if parsed_str != tstr:
raise ValueError("Invalid Isotime format")
components = [int(hh)]
if mm_ss:
components.extend(int(t) for t in mm_ss)
if ff:
components.append(int(ff.ljust(6, "0")))
return components + [0] * (4 - len(components))


def _parse_isoformat(dtstr):
# supported format is YYYY-mm-dd[THH[:MM[:SS[.fff[fff]]]]][+HH:MM[:SS[.ffffff]]]
dstr = dtstr[:10]
tstr = dtstr[11:]
try:
date = datetime.datetime.strptime(dstr, "%Y-%m-%d")
except ValueError as e:
raise ValueError("Invalid Isotime format") from e

if tstr:
# check for time zone
tz_pos = (tstr.find("-") + 1 or tstr.find("+") + 1)
if tz_pos > 0:
tzsign = -1 if tstr[tz_pos - 1] == "-" else 1
tz_comps = _parse_time_components(tstr[tz_pos:])
tz = tzsign * datetime.timedelta(
hours=tz_comps[0], minutes=tz_comps[1],
seconds=tz_comps[2], microseconds=tz_comps[3])
tstr = tstr[:tz_pos - 1]
else:
tz = datetime.timedelta(0)
time_comps = _parse_time_components(tstr)
date = date.replace(hour=time_comps[0], minute=time_comps[1],
second=time_comps[2], microsecond=time_comps[3])
date -= tz
elif len(dtstr) == 11:
raise ValueError("Invalid Isotime format")
return date
66 changes: 66 additions & 0 deletions tests/test_units/test_dateutil.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import pytest

from datetime import datetime
from aiogoogle.utils import _parse_isoformat


def test_iso_parser1():
assert _parse_isoformat("2021-02-06") == datetime(2021, 2, 6)


def test_iso_parser2():
assert _parse_isoformat("2021-02-06T14") == datetime(2021, 2, 6, 14)


def test_iso_parser3():
assert _parse_isoformat("2021-02-06T14:52") == datetime(2021, 2, 6, 14, 52)


def test_iso_parser4():
assert _parse_isoformat("2021-02-06T14:52:26") == \
datetime(2021, 2, 6, 14, 52, 26)


def test_iso_parser5():
assert _parse_isoformat("2021-02-06T14:52:26.123") == \
datetime(2021, 2, 6, 14, 52, 26, 123000)


def test_iso_parser6():
assert _parse_isoformat("2021-02-06T14:52:26.123456") == \
datetime(2021, 2, 6, 14, 52, 26, 123456)


def test_iso_parser7():
assert _parse_isoformat("2021-02-06T14:52:26.123456+01:30") == \
datetime(2021, 2, 6, 13, 22, 26, 123456)


def test_iso_parser8():
assert _parse_isoformat("2021-02-06T14:52:26.123456-01:00") == \
datetime(2021, 2, 6, 15, 52, 26, 123456)


def test_iso_malformed1():
with pytest.raises(ValueError):
_parse_isoformat("2021-02T14:52")


def test_iso_malformed2():
with pytest.raises(ValueError):
_parse_isoformat("2021-02-06T")


def test_iso_malformed3():
with pytest.raises(ValueError):
_parse_isoformat("2021-02-06T14.123")


def test_iso_malformed4():
with pytest.raises(ValueError):
_parse_isoformat("2021-02-06T14:52.123456")


def test_iso_malformed5():
with pytest.raises(ValueError):
_parse_isoformat("2021-02-06T14:52:26.1234")

0 comments on commit 3fddf69

Please sign in to comment.