mirror of
https://github.com/ansible/awx.git
synced 2026-03-15 07:57:29 -02:30
bump python-dateutil to latest
this change provides support for numerous bug fixes, along with support for parsing TZINFO= from rrule strings related: https://github.com/ansible/ansible-tower/issues/823 related: https://github.com/dateutil/dateutil/issues/614
This commit is contained in:
@@ -1,11 +1,10 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
import re
|
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import dateutil.rrule
|
import dateutil.rrule
|
||||||
from dateutil.tz import gettz, datetime_exists
|
from dateutil.tz import datetime_exists
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -57,10 +56,6 @@ class ScheduleManager(ScheduleFilterMethods, models.Manager):
|
|||||||
|
|
||||||
class Schedule(CommonModel, LaunchTimeConfig):
|
class Schedule(CommonModel, LaunchTimeConfig):
|
||||||
|
|
||||||
TZID_REGEX = re.compile(
|
|
||||||
"^(DTSTART;TZID=(?P<tzid>[^:]+)(?P<stamp>\:[0-9]+T[0-9]+))(?P<rrule> .*)$"
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
ordering = ['-next_run']
|
ordering = ['-next_run']
|
||||||
@@ -103,51 +98,23 @@ class Schedule(CommonModel, LaunchTimeConfig):
|
|||||||
def rrulestr(cls, rrule, **kwargs):
|
def rrulestr(cls, rrule, **kwargs):
|
||||||
"""
|
"""
|
||||||
Apply our own custom rrule parsing logic to support TZID=
|
Apply our own custom rrule parsing logic to support TZID=
|
||||||
|
|
||||||
python-dateutil doesn't _natively_ support `DTSTART;TZID=`; this
|
|
||||||
function parses out the TZID= component and uses it to produce the
|
|
||||||
`tzinfos` keyword argument to `dateutil.rrule.rrulestr()`. In this
|
|
||||||
way, we translate:
|
|
||||||
|
|
||||||
DTSTART;TZID=America/New_York:20180601T120000 RRULE:FREQ=DAILY;INTERVAL=1
|
|
||||||
|
|
||||||
...into...
|
|
||||||
|
|
||||||
DTSTART:20180601T120000TZID RRULE:FREQ=DAILY;INTERVAL=1
|
|
||||||
|
|
||||||
...and we pass a hint about the local timezone to dateutil's parser:
|
|
||||||
`dateutil.rrule.rrulestr(rrule, {
|
|
||||||
'tzinfos': {
|
|
||||||
'TZID': dateutil.tz.gettz('America/New_York')
|
|
||||||
}
|
|
||||||
})`
|
|
||||||
|
|
||||||
it's likely that we can remove the custom code that performs this
|
|
||||||
parsing if TZID= gains support in upstream dateutil:
|
|
||||||
https://github.com/dateutil/dateutil/pull/619
|
|
||||||
"""
|
"""
|
||||||
kwargs['forceset'] = True
|
kwargs['forceset'] = True
|
||||||
kwargs['tzinfos'] = {x: dateutil.tz.tzutc() for x in dateutil.parser.parserinfo().UTCZONE}
|
|
||||||
match = cls.TZID_REGEX.match(rrule)
|
|
||||||
if match is not None:
|
|
||||||
rrule = cls.TZID_REGEX.sub("DTSTART\g<stamp>TZI\g<rrule>", rrule)
|
|
||||||
timezone = gettz(match.group('tzid'))
|
|
||||||
kwargs['tzinfos']['TZI'] = timezone
|
|
||||||
x = dateutil.rrule.rrulestr(rrule, **kwargs)
|
x = dateutil.rrule.rrulestr(rrule, **kwargs)
|
||||||
|
|
||||||
for r in x._rrule:
|
for r in x._rrule:
|
||||||
|
if r._dtstart and r._dtstart.tzinfo is None:
|
||||||
|
raise ValueError(
|
||||||
|
'A valid TZID must be provided (e.g., America/New_York)'
|
||||||
|
)
|
||||||
|
|
||||||
if r._dtstart and r._until:
|
if r._dtstart and r._until:
|
||||||
|
# If https://github.com/dateutil/dateutil/pull/634 ever makes
|
||||||
|
# it into a python-dateutil release, we could remove this block.
|
||||||
if all((
|
if all((
|
||||||
r._dtstart.tzinfo != dateutil.tz.tzlocal(),
|
r._dtstart.tzinfo != dateutil.tz.tzlocal(),
|
||||||
r._until.tzinfo != dateutil.tz.tzutc(),
|
r._until.tzinfo != dateutil.tz.tzutc(),
|
||||||
)):
|
)):
|
||||||
# According to RFC5545 Section 3.3.10:
|
|
||||||
# https://tools.ietf.org/html/rfc5545#section-3.3.10
|
|
||||||
#
|
|
||||||
# > If the "DTSTART" property is specified as a date with UTC
|
|
||||||
# > time or a date with local time and time zone reference,
|
|
||||||
# > then the UNTIL rule part MUST be specified as a date with
|
|
||||||
# > UTC time.
|
|
||||||
raise ValueError('RRULE UNTIL values must be specified in UTC')
|
raise ValueError('RRULE UNTIL values must be specified in UTC')
|
||||||
|
|
||||||
if 'MINUTELY' in rrule or 'HOURLY' in rrule:
|
if 'MINUTELY' in rrule or 'HOURLY' in rrule:
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ def test_valid_survey_answer(post, admin_user, project, inventory, survey_spec_f
|
|||||||
("DTSTART:20300308T050000Z RRULE:FREQ=YEARLY;INTERVAL=1;BYYEARDAY=100", "BYYEARDAY not supported"), # noqa
|
("DTSTART:20300308T050000Z RRULE:FREQ=YEARLY;INTERVAL=1;BYYEARDAY=100", "BYYEARDAY not supported"), # noqa
|
||||||
("DTSTART:20300308T050000Z RRULE:FREQ=YEARLY;INTERVAL=1;BYWEEKNO=20", "BYWEEKNO not supported"),
|
("DTSTART:20300308T050000Z RRULE:FREQ=YEARLY;INTERVAL=1;BYWEEKNO=20", "BYWEEKNO not supported"),
|
||||||
("DTSTART:20300308T050000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=2000", "COUNT > 999 is unsupported"), # noqa
|
("DTSTART:20300308T050000Z RRULE:FREQ=DAILY;INTERVAL=1;COUNT=2000", "COUNT > 999 is unsupported"), # noqa
|
||||||
|
("DTSTART;TZID=US-Eastern:19961105T090000 RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=5", "A valid TZID must be provided"), # noqa
|
||||||
("DTSTART:20300308T050000Z RRULE:FREQ=REGULARLY;INTERVAL=1", "rrule parsing failed validation: invalid 'FREQ': REGULARLY"), # noqa
|
("DTSTART:20300308T050000Z RRULE:FREQ=REGULARLY;INTERVAL=1", "rrule parsing failed validation: invalid 'FREQ': REGULARLY"), # noqa
|
||||||
("DTSTART:20030925T104941Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=500;UNTIL=20040925T104941Z", "RRULE may not contain both COUNT and UNTIL"), # noqa
|
("DTSTART:20030925T104941Z RRULE:FREQ=DAILY;INTERVAL=10;COUNT=500;UNTIL=20040925T104941Z", "RRULE may not contain both COUNT and UNTIL"), # noqa
|
||||||
("DTSTART;TZID=America/New_York:20300308T050000Z RRULE:FREQ=DAILY;INTERVAL=1", "rrule parsing failed validation"),
|
("DTSTART;TZID=America/New_York:20300308T050000Z RRULE:FREQ=DAILY;INTERVAL=1", "rrule parsing failed validation"),
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ pycrypto==2.6.1
|
|||||||
pygerduty==0.37.0
|
pygerduty==0.37.0
|
||||||
pyOpenSSL==17.5.0
|
pyOpenSSL==17.5.0
|
||||||
pyparsing==2.2.0
|
pyparsing==2.2.0
|
||||||
|
python-dateutil==2.7.0 # contains support for TZINFO= parsing
|
||||||
python-logstash==0.4.6
|
python-logstash==0.4.6
|
||||||
python-memcached==1.59
|
python-memcached==1.59
|
||||||
python-radius==1.0
|
python-radius==1.0
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ pyjwt==1.6.0 # via adal, social-auth-core, twilio
|
|||||||
pyopenssl==17.5.0
|
pyopenssl==17.5.0
|
||||||
pyparsing==2.2.0
|
pyparsing==2.2.0
|
||||||
pyrad==2.1 # via django-radius
|
pyrad==2.1 # via django-radius
|
||||||
python-dateutil==2.6.1 # via adal, azure-cosmosdb-table, azure-storage-common, botocore
|
python-dateutil==2.7.0
|
||||||
python-ldap==2.5.2 # via django-auth-ldap
|
python-ldap==2.5.2 # via django-auth-ldap
|
||||||
python-logstash==0.4.6
|
python-logstash==0.4.6
|
||||||
python-memcached==1.59
|
python-memcached==1.59
|
||||||
|
|||||||
Reference in New Issue
Block a user