File: alarm.py

package info (click to toggle)
python-recurring-ical-events 3.8.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,584 kB
  • sloc: python: 4,476; makefile: 84
file content (93 lines) | stat: -rw-r--r-- 3,262 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""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"]