Merge pull request #1982 from metallerok/recurrence_all_day_comparsion

Recurrence all day comparsion
This commit is contained in:
Peter Bieringer
2026-02-07 08:27:01 +01:00
committed by GitHub
3 changed files with 64 additions and 16 deletions

View File

@@ -395,7 +395,7 @@ def _expand(
time_range_end = time_range_end.replace(tzinfo=None) time_range_end = time_range_end.replace(tzinfo=None)
for vevent in vevents_overridden: for vevent in vevents_overridden:
_strip_single_event(vevent, dt_format) _strip_single_event(vevent, dt_format, all_day_event)
duration = None duration = None
if hasattr(base_vevent, "dtend"): if hasattr(base_vevent, "dtend"):
@@ -457,7 +457,7 @@ def _expand(
.format(max_occurrence)) .format(max_occurrence))
_strip_component(vevent_component) _strip_component(vevent_component)
_strip_single_event(base_vevent, dt_format) _strip_single_event(base_vevent, dt_format, all_day_event)
i_overridden = 0 i_overridden = 0
@@ -480,7 +480,13 @@ def _expand(
continue continue
# Check for overridden instances # Check for overridden instances
i_overridden, vevent = _find_overridden(i_overridden, vevents_overridden, recurrence_utc, dt_format) i_overridden, vevent = _find_overridden(
i_overridden,
vevents_overridden,
recurrence_utc,
dt_format,
all_day_event,
)
if not vevent: if not vevent:
# Create new instance from recurrence # Create new instance from recurrence
@@ -568,15 +574,20 @@ def _expand(
return element, len(filtered_vevents) return element, len(filtered_vevents)
def _convert_timezone(vevent: vobject.icalendar.RecurringComponent, def _convert_timezone(
name_prop: str, vevent: vobject.icalendar.RecurringComponent,
name_content_line: str): name_prop: str,
name_content_line: str,
all_day_event: bool = False
):
prop = getattr(vevent, name_prop, None) prop = getattr(vevent, name_prop, None)
if prop: if prop:
if type(prop.value) is datetime.date: if type(prop.value) is datetime.date:
date_time = datetime.datetime.fromordinal( date_time = datetime.datetime.fromordinal(
prop.value.toordinal() prop.value.toordinal()
).replace(tzinfo=datetime.timezone.utc) )
if not all_day_event:
date_time = date_time.replace(tzinfo=datetime.timezone.utc)
else: else:
date_time = prop.value.astimezone(datetime.timezone.utc) date_time = prop.value.astimezone(datetime.timezone.utc)
@@ -591,10 +602,14 @@ def _convert_to_utc(vevent: vobject.icalendar.RecurringComponent,
setattr(vevent, name_prop, ContentLine(name=prop.name, value=prop.value.strftime(dt_format), params=[])) setattr(vevent, name_prop, ContentLine(name=prop.name, value=prop.value.strftime(dt_format), params=[]))
def _strip_single_event(vevent: vobject.icalendar.RecurringComponent, dt_format: str) -> None: def _strip_single_event(
_convert_timezone(vevent, 'dtstart', 'DTSTART') vevent: vobject.icalendar.RecurringComponent,
_convert_timezone(vevent, 'dtend', 'DTEND') dt_format: str,
_convert_timezone(vevent, 'recurrence_id', 'RECURRENCE-ID') all_day_event: bool = False,
) -> None:
_convert_timezone(vevent, 'dtstart', 'DTSTART', all_day_event)
_convert_timezone(vevent, 'dtend', 'DTEND', all_day_event)
_convert_timezone(vevent, 'recurrence_id', 'RECURRENCE-ID', all_day_event)
# There is something strange behaviour during serialization native datetime, so converting manually # There is something strange behaviour during serialization native datetime, so converting manually
_convert_to_utc(vevent, 'dtstart', dt_format) _convert_to_utc(vevent, 'dtstart', dt_format)
@@ -675,13 +690,13 @@ def _find_overridden(
start: int, start: int,
vevents: List[vobject.icalendar.RecurringComponent], vevents: List[vobject.icalendar.RecurringComponent],
dt: datetime.datetime, dt: datetime.datetime,
dt_format: str dt_format: str,
all_day_event: bool,
) -> Tuple[int, Optional[vobject.icalendar.RecurringComponent]]: ) -> Tuple[int, Optional[vobject.icalendar.RecurringComponent]]:
for i in range(start, len(vevents)): for i in range(start, len(vevents)):
dt_event = datetime.datetime.strptime( dt_event = datetime.datetime.strptime(vevents[i].recurrence_id.value, dt_format)
vevents[i].recurrence_id.value, if not all_day_event:
dt_format dt_event = dt_event.replace(tzinfo=datetime.timezone.utc)
).replace(tzinfo=datetime.timezone.utc)
if dt_event == dt: if dt_event == dt:
return (i + 1, vevents[i]) return (i + 1, vevents[i])
return (start, None) return (start, None)

View File

@@ -0,0 +1,21 @@
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Radicale//Test//EN
BEGIN:VEVENT
DTSTART;VALUE=DATE:20060102
DTEND;VALUE=DATE:20060103
RRULE:FREQ=DAILY;COUNT=3
UID:event_full_day_rrule_overridden
SUMMARY:All day recurring
END:VEVENT
BEGIN:VEVENT
DTSTART;VALUE=DATE:20060110
DTEND;VALUE=DATE:20060111
RECURRENCE-ID;VALUE=DATE:20060103
UID:event_full_day_rrule_overridden
SUMMARY:Overridden instance
END:VEVENT
END:VCALENDAR

View File

@@ -738,3 +738,15 @@ permissions: RrWw""")
assert event_id in error_logs[0] assert event_id in error_logs[0]
assert "base DTSTART is datetime" in error_logs[0] assert "base DTSTART is datetime" in error_logs[0]
assert "override RECURRENCE-ID is date" in error_logs[0] assert "override RECURRENCE-ID is date" in error_logs[0]
def test_report_with_expand_property_all_day_event_overridden(self) -> None:
self._test_expand(
"event_full_day_rrule_overridden",
"20060101T000000Z",
"20060111T235959Z",
["RECURRENCE-ID:20060102", "RECURRENCE-ID:20060104", "RECURRENCE-ID:20060103"],
["DTSTART:20060102", "DTSTART:20060104", "DTSTART:20060110"],
["DTEND:20060103", "DTEND:20060105", "DTEND:20060111"],
ONLY_DATES,
2
)