kopia lustrzana https://github.com/collective/icalendar
Fix for TZID forward references to VTIMEZONE
rodzic
d22fb38c3f
commit
88b8d62df5
|
@ -18,6 +18,7 @@ New features:
|
|||
|
||||
Bug fixes:
|
||||
|
||||
- Fix to permit TZID forward references to VTIMEZONEs
|
||||
- ...
|
||||
|
||||
6.1.2 (2025-03-19)
|
||||
|
@ -137,9 +138,7 @@ New features:
|
|||
Bug fixes:
|
||||
|
||||
- Fix link to stable release of tox in documentation.
|
||||
- Fix a bad ``bytes`` replace in ``unescape_char``.
|
||||
- Handle ``ValueError`` in ``vBinary.from_ical``.
|
||||
- Ignore the BOM character in incorrectly encoded ics files.
|
||||
- Fix a bad bytes replace in unescape_char.
|
||||
|
||||
6.0.0a0 (2024-07-03)
|
||||
--------------------
|
||||
|
|
|
@ -730,7 +730,7 @@ class Event(Component):
|
|||
'RSTATUS', 'RELATED', 'RESOURCES', 'RDATE', 'RRULE'
|
||||
)
|
||||
ignore_exceptions = True
|
||||
|
||||
|
||||
@property
|
||||
def alarms(self) -> Alarms:
|
||||
"""Compute the alarm times for this component.
|
||||
|
@ -1007,7 +1007,7 @@ class Journal(Component):
|
|||
@property
|
||||
def start(self) -> date:
|
||||
"""The start of the Journal.
|
||||
|
||||
|
||||
The "DTSTART"
|
||||
property is used to specify the calendar date with which the
|
||||
journal entry is associated.
|
||||
|
@ -1016,14 +1016,14 @@ class Journal(Component):
|
|||
if start is None:
|
||||
raise IncompleteComponent("No DTSTART given.")
|
||||
return start
|
||||
|
||||
|
||||
@start.setter
|
||||
def start(self, value: datetime|date) -> None:
|
||||
"""Set the start of the journal."""
|
||||
self.DTSTART = value
|
||||
|
||||
end = start
|
||||
|
||||
|
||||
@property
|
||||
def duration(self) -> timedelta:
|
||||
"""The journal has no duration: timedelta(0)."""
|
||||
|
@ -1565,20 +1565,20 @@ class Alarm(Component):
|
|||
if trigger is None:
|
||||
raise ValueError("You must set a TRIGGER before setting the RELATED parameter.")
|
||||
trigger.params["RELATED"] = value
|
||||
|
||||
|
||||
class Triggers(NamedTuple):
|
||||
"""The computed times of alarm triggers.
|
||||
|
||||
start - triggers relative to the start of the Event or Todo (timedelta)
|
||||
|
||||
|
||||
end - triggers relative to the end of the Event or Todo (timedelta)
|
||||
|
||||
|
||||
absolute - triggers at a datetime in UTC
|
||||
"""
|
||||
start: tuple[timedelta]
|
||||
end: tuple[timedelta]
|
||||
absolute: tuple[datetime]
|
||||
|
||||
|
||||
@property
|
||||
def triggers(self):
|
||||
"""The computed triggers of an Alarm.
|
||||
|
@ -1638,6 +1638,38 @@ class Calendar(Component):
|
|||
"""Return the calendar example with the given name."""
|
||||
return cls.from_ical(get_example("calendars", name))
|
||||
|
||||
@classmethod
|
||||
def from_ical(cls, st, multiple=False):
|
||||
comps = Component.from_ical(st, multiple=True)
|
||||
all_timezones_so_far = True
|
||||
for comp in comps:
|
||||
for component in comp.walk():
|
||||
if type(component) == Timezone:
|
||||
if all_timezones_so_far:
|
||||
pass
|
||||
else:
|
||||
# If a preceding component refers to a VTIMEZONE defined later in the source st
|
||||
# (forward references are allowed by RFC 5545), then the earlier component may have
|
||||
# the wrong timezone attached.
|
||||
# However, during computation of comps, all VTIMEZONEs observed do end up in
|
||||
# the timezone cache. So simply re-running from_ical will rely on the cache
|
||||
# for those forward references to produce the correct result.
|
||||
# See test_create_america_new_york_forward_reference.
|
||||
return Component.from_ical(st, multiple)
|
||||
else:
|
||||
all_timezones_so_far = False
|
||||
|
||||
# No potentially forward VTIMEZONEs to worry about
|
||||
if multiple:
|
||||
return comps
|
||||
if len(comps) > 1:
|
||||
raise ValueError(cls._format_error(
|
||||
'Found multiple components where only one is allowed', st))
|
||||
if len(comps) < 1:
|
||||
raise ValueError(cls._format_error(
|
||||
'Found no components where exactly one is required', st))
|
||||
return comps[0]
|
||||
|
||||
@property
|
||||
def events(self) -> list[Event]:
|
||||
"""All event components in the calendar.
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
BEGIN:VCALENDAR
|
||||
BEGIN:VEVENT
|
||||
UID:noend123
|
||||
DTSTART;TZID=custom_America/New_York_Forward_reference;VALUE=DATE-TIME:20140829T080000
|
||||
DTSTART;TZID=custom_America/New_York_Forward_reference;VALUE=DATE-TIME:20140829T100000
|
||||
SUMMARY:an event with a custom tz name
|
||||
END:VEVENT
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:custom_America/New_York_Forward_reference
|
||||
LAST-MODIFIED:20050809T050000Z
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19670430T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU;UNTIL=19730429T070000Z
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
TZNAME:EDT
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
DTSTART:19671029T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU;UNTIL=20061029T060000Z
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
TZNAME:EST
|
||||
END:STANDARD
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19740106T020000
|
||||
RDATE:19750223T020000
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
TZNAME:EDT
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19760425T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=-1SU;UNTIL=19860427T070000Z
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
TZNAME:EDT
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:19870405T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU;UNTIL=20060402T070000Z
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
TZNAME:EDT
|
||||
END:DAYLIGHT
|
||||
BEGIN:DAYLIGHT
|
||||
DTSTART:20070311T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
|
||||
TZOFFSETFROM:-0500
|
||||
TZOFFSETTO:-0400
|
||||
TZNAME:EDT
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
DTSTART:20071104T020000
|
||||
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
|
||||
TZOFFSETFROM:-0400
|
||||
TZOFFSETTO:-0500
|
||||
TZNAME:EST
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
END:VCALENDAR
|
|
@ -138,6 +138,11 @@ def test_create_america_new_york(calendars, tzp):
|
|||
dt = cal.events[0].start
|
||||
assert tzid_from_dt(dt) in ("custom_America/New_York", "EDT")
|
||||
|
||||
def test_create_america_new_york_forward_reference(calendars, tzp):
|
||||
"""testing America/New_York variant with VTIMEZONE as a forward reference"""
|
||||
cal = calendars.america_new_york_forward_reference
|
||||
dt = cal.walk('VEVENT')[0]['DTSTART'][0].dt
|
||||
assert tzid_from_dt(dt) in ('custom_America/New_York_Forward_reference', "EDT")
|
||||
|
||||
def test_america_new_york_with_pytz(calendars, tzp, pytz_only):
|
||||
"""Create a custom timezone with pytz and test the transition times."""
|
||||
|
|
Ładowanie…
Reference in New Issue