1
0
mirror of https://github.com/ansible/awx.git synced 2024-10-27 09:25:10 +03:00

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:
Ryan Petrello 2018-03-12 09:39:19 -04:00
parent dcab97f94f
commit 44adab0e9e
4 changed files with 11 additions and 42 deletions

View File

@ -1,11 +1,10 @@
# Copyright (c) 2015 Ansible, Inc.
# All Rights Reserved.
import re
import logging
import datetime
import dateutil.rrule
from dateutil.tz import gettz, datetime_exists
from dateutil.tz import datetime_exists
# Django
from django.db import models
@ -57,10 +56,6 @@ class ScheduleManager(ScheduleFilterMethods, models.Manager):
class Schedule(CommonModel, LaunchTimeConfig):
TZID_REGEX = re.compile(
"^(DTSTART;TZID=(?P<tzid>[^:]+)(?P<stamp>\:[0-9]+T[0-9]+))(?P<rrule> .*)$"
)
class Meta:
app_label = 'main'
ordering = ['-next_run']
@ -103,51 +98,23 @@ class Schedule(CommonModel, LaunchTimeConfig):
def rrulestr(cls, rrule, **kwargs):
"""
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['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)
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 https://github.com/dateutil/dateutil/pull/634 ever makes
# it into a python-dateutil release, we could remove this block.
if all((
r._dtstart.tzinfo != dateutil.tz.tzlocal(),
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')
if 'MINUTELY' in rrule or 'HOURLY' in rrule:

View File

@ -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;BYWEEKNO=20", "BYWEEKNO not supported"),
("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: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"),

View File

@ -38,6 +38,7 @@ pycrypto==2.6.1
pygerduty==0.37.0
pyOpenSSL==17.5.0
pyparsing==2.2.0
python-dateutil==2.7.0 # contains support for TZINFO= parsing
python-logstash==0.4.6
python-memcached==1.59
python-radius==1.0

View File

@ -182,7 +182,7 @@ pyjwt==1.6.0 # via adal, social-auth-core, twilio
pyopenssl==17.5.0
pyparsing==2.2.0
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-logstash==0.4.6
python-memcached==1.59