fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""Adapter for VTODO."""
|
||||
|
||||
from recurring_ical_events.adapters.component import ComponentAdapter
|
||||
from recurring_ical_events.constants import DATE_MAX_DT, DATE_MIN_DT
|
||||
from recurring_ical_events.types import Time
|
||||
from recurring_ical_events.util import (
|
||||
convert_to_datetime,
|
||||
is_date,
|
||||
normalize_pytz,
|
||||
)
|
||||
|
||||
|
||||
class TodoAdapter(ComponentAdapter):
|
||||
"""Unified access to TODOs."""
|
||||
|
||||
@staticmethod
|
||||
def component_name() -> str:
|
||||
"""The icalendar component name."""
|
||||
return "VTODO"
|
||||
|
||||
@property
|
||||
def end_property(self) -> str:
|
||||
"""DUE"""
|
||||
return "DUE"
|
||||
|
||||
@property
|
||||
def raw_start(self) -> Time:
|
||||
"""Return DTSTART if it set, do not panic if it's not set."""
|
||||
## easy case - DTSTART set
|
||||
start = self._component.get("DTSTART")
|
||||
if start is not None:
|
||||
return start.dt
|
||||
## Tasks may have DUE set, but no DTSTART.
|
||||
## Let's assume 0 duration and return the DUE
|
||||
due = self._component.get("DUE")
|
||||
if due is not None:
|
||||
return due.dt
|
||||
|
||||
## Assume infinite time span if neither is given
|
||||
## (see the comments under _get_event_end)
|
||||
return DATE_MIN_DT
|
||||
|
||||
@property
|
||||
def raw_end(self) -> Time:
|
||||
"""Return DUE or DTSTART+DURATION or something"""
|
||||
## Easy case - DUE is set
|
||||
end = self._component.get("DUE")
|
||||
if end is not None:
|
||||
return end.dt
|
||||
|
||||
dtstart = self._component.get("DTSTART")
|
||||
|
||||
## DURATION can be specified instead of DUE.
|
||||
duration = self._component.get("DURATION")
|
||||
## It is no requirement that DTSTART is set.
|
||||
## Perhaps duration is a time estimate rather than an indirect
|
||||
## way to set DUE.
|
||||
if duration is not None and dtstart is not None:
|
||||
start = dtstart.dt
|
||||
if duration.dt.seconds != 0 and is_date(start):
|
||||
start = convert_to_datetime(start, None)
|
||||
return normalize_pytz(start + duration.dt)
|
||||
|
||||
## According to the RFC, a VEVENT without an end/duration
|
||||
## is to be considered to have zero duration. Assuming the
|
||||
## same applies to VTODO.
|
||||
if dtstart:
|
||||
return dtstart.dt
|
||||
|
||||
## The RFC says this about VTODO:
|
||||
## > A "VTODO" calendar component without the "DTSTART" and "DUE" (or
|
||||
## > "DURATION") properties specifies a to-do that will be associated
|
||||
## > with each successive calendar date, until it is completed.
|
||||
## It can be interpreted in different ways, though probably it may
|
||||
## be considered equivalent with a DTSTART in the infinite past and DUE
|
||||
## in the infinite future?
|
||||
return DATE_MAX_DT
|
||||
|
||||
|
||||
__all__ = ["TodoAdapter"]
|
||||
Reference in New Issue
Block a user