Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 11 additions & 39 deletions caldav/calendarobjectresource.py
Original file line number Diff line number Diff line change
Expand Up @@ -510,19 +510,10 @@ def get_due(self):
"""
A VTODO may have due or duration set. Return or calculate due.

WARNING: this method is likely to be deprecated and moved to
the icalendar library. If you decide to use it, please put
caldav<3.0 in the requirements.
DEPRECATION WARNING: this method is likely to be removed in
caldav v3.0. Use self.icalendar_component.end instead.
"""
i = self.icalendar_component
if "DUE" in i:
return i["DUE"].dt
elif "DTEND" in i:
return i["DTEND"].dt
elif "DURATION" in i and "DTSTART" in i:
return i["DTSTART"].dt + i["DURATION"].dt
else:
return None
return self.icalendar_component.end

get_dtend = get_due

Expand Down Expand Up @@ -1426,7 +1417,11 @@ def _has_data(self) -> bool:
## ===================================================================

def get_duration(self) -> timedelta:
"""According to the RFC, either DURATION or DUE should be set
"""
DEPRECATION WARNING: This method may be removed in version 3.0.
Use self.icalendar_component.duration instead.

According to the RFC, either DURATION or DUE should be set
for a task, but never both - implicitly meaning that DURATION
is the difference between DTSTART and DUE (personally I
believe that's stupid. If a task takes five minutes to
Expand All @@ -1442,31 +1437,8 @@ def get_duration(self) -> timedelta:
TODO: should be fixed for Event class as well (only difference
is that DTEND is used rather than DUE) and possibly also for
Journal (defaults to one day, probably?)

WARNING: this method is likely to be deprecated and moved to
the icalendar library. If you decide to use it, please put
caldav<3.0 in the requirements.
"""
i = self.icalendar_component
return self._get_duration(i)

def _get_duration(self, i):
if "DURATION" in i:
return i["DURATION"].dt
elif "DTSTART" in i and self._ENDPARAM in i:
end = i[self._ENDPARAM].dt
start = i["DTSTART"].dt
## We do have a problem here if one is a date and the other is a
## datetime. This is NOT explicitly defined as a technical
## breach in the RFC, so we need to work around it.
if isinstance(end, datetime) != isinstance(start, datetime):
start = datetime(start.year, start.month, start.day)
end = datetime(end.year, end.month, end.day)
return end - start
elif "DTSTART" in i and not isinstance(i["DTSTART"], datetime):
return timedelta(days=1)
else:
return timedelta(0)
return self.icalendar_component.duration


class Event(CalendarObjectResource):
Expand Down Expand Up @@ -1616,7 +1588,7 @@ def _next(self, ts=None, i=None, dtstart=None, rrule=None, by=None, no_count=Tru
else:
dtstart = ts or datetime.now()
else:
dtstart = ts or datetime.now() - self._get_duration(i)
dtstart = ts or datetime.now() - i.duration
## dtstart should be compared to the completion timestamp, which
## is set in UTC in the complete() method. However, dtstart
## may be a naïve or a floating timestamp
Expand Down Expand Up @@ -1747,7 +1719,7 @@ def _complete_recurring_thisandfuture(self, completion_timestamp) -> None:

rrule = rrule2 or rrule

duration = self._get_duration(i=prev)
duration = prev.duration
thisandfuture.pop("DTSTART", None)
thisandfuture.pop("DUE", None)
next_dtstart = self._next(i=prev, rrule=rrule, ts=completion_timestamp)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ dependencies = [
"niquests",
"recurring-ical-events>=2.0.0",
"typing_extensions;python_version<'3.11'",
"icalendar>6.0.0",
"icalendar>=7.0.0a2",
"icalendar-searcher>=1.0.0,<2",
"dnspython",
"python-dateutil",
Expand Down
Loading