1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-08-10 18:40:53 +00:00

recurring events brought to rfc4791

This commit is contained in:
Georgiy 2023-03-30 23:13:00 +03:00
parent a07813ecc9
commit 72103c30c2

View file

@ -23,6 +23,7 @@ import posixpath
import socket
import copy
import xml.etree.ElementTree as ET
from vobject.base import ContentLine
from http import client
from typing import (
Callable, Iterable, Iterator,
@ -197,28 +198,74 @@ def _expand(
) -> List[ET.Element]:
expanded = [element]
for component in item.vobject_item.components():
if component.name != 'VEVENT':
continue
if hasattr(item.vobject_item.vevent, "rrule"):
rulleset = item.vobject_item.vevent.getrruleset()
recurrences = rulleset.between(start, end)
recurring_item = _make_vobject_recurring_item(item)
if hasattr(component, "rrule"):
rulleset = component.getrruleset()
recurrences = rulleset.between(start, end)
expanded = []
for recurrence_dt in recurrences:
try:
delattr(recurring_item.vobject_item.vevent, 'recurrence-id')
except AttributeError:
pass
expanded = []
for recurrence_dt in recurrences:
try:
delattr(item.vobject_item.vevent, 'recurrence-id')
except AttributeError:
pass
recurrence_utc = recurrence_dt.astimezone(datetime.timezone.utc)
item.vobject_item.vevent.add('RECURRENCE-ID').value = recurrence_dt
element.text = item.vobject_item.serialize()
expanded.append(element)
recurring_item.vobject_item.vevent.recurrence_id = ContentLine(
name='RECURRENCE-ID',
value=recurrence_utc.strftime('%Y%m%dT%H%M%SZ'), params={}
)
element = copy.copy(element)
element.text = recurring_item.vobject_item.serialize()
expanded.append(element)
return expanded
def _make_vobject_recurring_item(
item: radicale_item.Item
) -> radicale_item.Item:
# https://www.rfc-editor.org/rfc/rfc4791#section-9.6.5
# The returned calendar components MUST NOT use recurrence
# properties (i.e., EXDATE, EXRULE, RDATE, and RRULE) and MUST NOT
# have reference to or include VTIMEZONE components. Date and local
# time with reference to time zone information MUST be converted
# into date with UTC time.
item = copy.copy(item)
vevent = item.vobject_item.vevent
start_utc = vevent.dtstart.value.astimezone(datetime.timezone.utc)
end_utc = vevent.dtend.value.astimezone(datetime.timezone.utc)
vevent.dtstart = ContentLine(
name='DTSTART',
value=start_utc.strftime('%Y%m%dT%H%M%SZ'), params={})
vevent.dtend = ContentLine(
name='DTEND',
value=end_utc.strftime('%Y%m%dT%H%M%SZ'), params={})
timezones_to_remove = []
for component in item.vobject_item.components():
if component.name == 'VTIMEZONE':
timezones_to_remove.append(component)
for timezone in timezones_to_remove:
item.vobject_item.remove(timezone)
try:
delattr(item.vobject_item.vevent, 'rrule')
delattr(item.vobject_item.vevent, 'exdate')
delattr(item.vobject_item.vevent, 'exrule')
delattr(item.vobject_item.vevent, 'rdate')
except AttributeError:
pass
return item
def xml_item_response(base_prefix: str, href: str,
found_props: Sequence[ET.Element] = (),
not_found_props: Sequence[ET.Element] = (),