Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
3.2 KiB
Python
94 lines
3.2 KiB
Python
"""Selection for alarms."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import contextlib
|
|
import datetime
|
|
from typing import TYPE_CHECKING, Sequence
|
|
|
|
from recurring_ical_events.adapters.event import EventAdapter
|
|
from recurring_ical_events.adapters.todo import TodoAdapter
|
|
from recurring_ical_events.selection.base import SelectComponents
|
|
|
|
if TYPE_CHECKING:
|
|
from icalendar.cal import Component
|
|
|
|
from recurring_ical_events.adapters.component import ComponentAdapter
|
|
from recurring_ical_events.series import Series
|
|
|
|
|
|
class Alarms(SelectComponents):
|
|
"""Select alarms and find their times.
|
|
|
|
By default, alarms from TODOs and events are collected.
|
|
You can use this to change which alarms are collected:
|
|
|
|
Alarms((EventAdapter,))
|
|
Alarms((TodoAdapter,))
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
parents: tuple[type[ComponentAdapter] | SelectComponents] = (
|
|
EventAdapter,
|
|
TodoAdapter,
|
|
),
|
|
):
|
|
self.parents = parents
|
|
|
|
@staticmethod
|
|
def component_name():
|
|
"""The name of the component we calculate."""
|
|
return "VALARM"
|
|
|
|
def collect_parent_series_from(
|
|
self, source: Component, suppress_errors: tuple[Exception]
|
|
) -> Sequence[Series]:
|
|
"""Collect the parent components of alarms."""
|
|
return [
|
|
s
|
|
for parent in self.parents
|
|
for s in parent.collect_series_from(source, suppress_errors)
|
|
]
|
|
|
|
def collect_series_from(
|
|
self, source: Component, suppress_errors: tuple[Exception]
|
|
) -> Sequence[Series]:
|
|
"""Collect all TODOs and Alarms from VEVENTs and VTODOs.
|
|
|
|
suppress_errors - a list of errors that should be suppressed.
|
|
A Series of events with such an error is removed from all results.
|
|
"""
|
|
from recurring_ical_events.series.alarm import (
|
|
AbsoluteAlarmSeries,
|
|
AlarmSeriesRelativeToEnd,
|
|
AlarmSeriesRelativeToStart,
|
|
)
|
|
|
|
absolute_alarms = AbsoluteAlarmSeries()
|
|
result = []
|
|
# alarms might be copied several times. We only compute them once.
|
|
for series in self.collect_parent_series_from(source, suppress_errors):
|
|
used_alarms = []
|
|
for component in series.components:
|
|
for alarm in component.alarms:
|
|
with contextlib.suppress(suppress_errors):
|
|
trigger = alarm.TRIGGER
|
|
if trigger is None or alarm in used_alarms:
|
|
continue
|
|
if isinstance(trigger, datetime.datetime):
|
|
absolute_alarms.add(alarm, component)
|
|
used_alarms.append(alarm)
|
|
elif alarm.TRIGGER_RELATED == "START":
|
|
result.append(AlarmSeriesRelativeToStart(alarm, series))
|
|
used_alarms.append(alarm)
|
|
elif alarm.TRIGGER_RELATED == "END":
|
|
result.append(AlarmSeriesRelativeToEnd(alarm, series))
|
|
used_alarms.append(alarm)
|
|
if not absolute_alarms.is_empty():
|
|
result.append(absolute_alarms)
|
|
return result
|
|
|
|
|
|
__all__ = ["Alarms"]
|