o
    .j0                     @  s   d Z ddlmZ ddlmZmZmZ ddlmZmZ ddl	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ erRddlZdd	lmZ G d
d deZdgZ dS )z:rfc:`5545` VALARM component.    )annotations)datedatetime	timedelta)TYPE_CHECKING
NamedTuple)CONCEPTS_TYPE_SETTERLINKS_TYPE_SETTERRELATED_TO_TYPE_SETTERattendees_propertycreate_single_propertydescription_propertyproperty_del_durationproperty_get_durationproperty_set_durationsingle_int_propertysingle_string_propertysingle_utc_propertysummary_propertyuid_property)	Component)get_exampleN)vCalAddressc                      s   e Zd ZdZdZdZdZdZdZe	ddd	Z
eeeed
ZeddZeddeefeeB dB dZed2ddZejd3ddZG dd deZedd ZedejdZeZe Z!e"Z#e$								d4d5 fd,d-Z%e$d6d7d0d1Z&  Z'S )8Alarma  
    A "VALARM" calendar component is a grouping of component
    properties that defines an alarm or reminder for an event or a
    to-do. For example, it may be used to define a reminder for a
    pending event or an overdue to-do.

    Example:

        The following example creates an alarm which uses an audio file
        from an FTP server.

        .. code-block:: pycon

            >>> from icalendar import Alarm
            >>> alarm = Alarm.example()
            >>> print(alarm.to_ical().decode())
            BEGIN:VALARM
            ACTION:AUDIO
            ATTACH;FMTTYPE=audio/basic:ftp://example.com/pub/sounds/bell-01.aud
            DURATION:PT15M
            REPEAT:4
            TRIGGER;VALUE=DATE-TIME:19970317T133000Z
            END:VALARM
    VALARM)ACTIONTRIGGER)
ATTACHr   DESCRIPTIONSUMMARYr   DURATIONREPEATUID	PROXIMITYACKNOWLEDGED))r    r!   )r   ATTENDEE)r%   r   z
RELATED-TOr!   r   as  The number of additional times the alarm is triggered after the initial trigger.

        Defaults to ``0``, meaning the alarm fires once. To repeat the alarm,
        set both :attr:`REPEAT` and :attr:`DURATION`. The :attr:`DURATION`
        sets the gap between repetitions. ``REPEAT`` is the count of *additional*
        triggers, so a ``REPEAT`` of ``2`` produces three alarms in total
        (the initial trigger plus two repeats).

        Conforming with :rfc:`5545#section-3.8.6.2`, this property can appear
        once in an :class:`~icalendar.cal.alarm.Alarm` component and must be
        paired with :attr:`DURATION`.

        Example:
            Build an alarm that fires once and then repeats twice at
            five-minute intervals.

            .. code-block:: pycon

                >>> from datetime import timedelta
                >>> from icalendar import Alarm
                >>> alarm = Alarm()
                >>> alarm.TRIGGER = timedelta(minutes=-15)
                >>> alarm.DURATION = timedelta(minutes=5)
                >>> alarm.REPEAT = 2
                >>> alarm.REPEAT
                2
        a  The delay between repeated triggers of a repeating alarm.

        Returns a :class:`datetime.timedelta` or ``None`` when the alarm
        has no :attr:`DURATION` set. Setting this attribute accepts a
        :class:`~datetime.timedelta`; deleting it removes the property
        from the component.

        :attr:`DURATION` is meaningful only for repeating alarms and must
        be paired with :attr:`REPEAT`. The two together produce
        ``REPEAT`` additional triggers, each spaced by ``DURATION`` after
        the initial trigger.

        Conforming with :rfc:`5545#section-3.8.2.5`, the ``DURATION`` property
        can appear once in an :class:`~icalendar.cal.alarm.Alarm` component.

        Example:
            Pair :attr:`DURATION` with :attr:`REPEAT` to produce three
            triggers spaced ten minutes apart.

            .. code-block:: pycon

                >>> from datetime import timedelta
                >>> from icalendar import Alarm
                >>> alarm = Alarm()
                >>> alarm.TRIGGER = timedelta(minutes=-30)
                >>> alarm.DURATION = timedelta(minutes=10)
                >>> alarm.REPEAT = 2
                >>> alarm.DURATION
                datetime.timedelta(seconds=600)
        r$   a  This is defined in RFC 9074:

    Purpose: This property specifies the UTC date and time at which the
    corresponding alarm was last sent or acknowledged.

    This property is used to specify when an alarm was last sent or acknowledged.
    This allows clients to determine when a pending alarm has been acknowledged
    by a calendar user so that any alerts can be dismissed across multiple devices.
    It also allows clients to track repeating alarms or alarms on recurring events or
    to-dos to ensure that the right number of missed alarms can be tracked.

    Clients SHOULD set this property to the current date-time value in UTC
    when a calendar user acknowledges a pending alarm. Certain kinds of alarms,
    such as email-based alerts, might not provide feedback as to when the calendar user
    sees them. For those kinds of alarms, the client SHOULD set this property
    when the alarm is triggered and the action is successfully carried out.

    When an alarm is triggered on a client, clients can check to see if an "ACKNOWLEDGED"
    property is present. If it is, and the value of that property is greater than or
    equal to the computed trigger time for the alarm, then the client SHOULD NOT trigger
    the alarm. Similarly, if an alarm has been triggered and
    an "alert" has been presented to a calendar user, clients can monitor
    the iCalendar data to determine whether an "ACKNOWLEDGED" property is added or
    changed in the alarm component. If the value of any "ACKNOWLEDGED" property
    in the alarm changes and is greater than or equal to the trigger time of the alarm,
    then clients SHOULD dismiss or cancel any "alert" presented to the calendar user.
    r   dtNa2  Purpose:  This property specifies when an alarm will trigger.

    Value Type:  The default value type is DURATION.  The value type can
    be set to a DATE-TIME value type, in which case the value MUST
    specify a UTC-formatted DATE-TIME value.

    Either a positive or negative duration may be specified for the
    "TRIGGER" property.  An alarm with a positive duration is
    triggered after the associated start or end of the event or to-do.
    An alarm with a negative duration is triggered before the
    associated start or end of the event or to-do.returnstrc                 C  s$   |  d}|du rdS |j ddS )a  The RELATED parameter of the TRIGGER property.

        Values are either "START" (default) or "END".

        A value of START will set the alarm to trigger off the
        start of the associated event or to-do.  A value of END will set
        the alarm to trigger off the end of the associated event or to-do.

        In this example, we create an alarm that triggers two hours after the
        end of its parent component:

        >>> from icalendar import Alarm
        >>> from datetime import timedelta
        >>> alarm = Alarm()
        >>> alarm.TRIGGER = timedelta(hours=2)
        >>> alarm.TRIGGER_RELATED = "END"
        r   NSTARTRELATED)getparams)selftrigger r/   H/home/thesage/.local/lib/python3.10/site-packages/icalendar/cal/alarm.pyTRIGGER_RELATED   s   
zAlarm.TRIGGER_RELATEDvaluec                 C  s(   |  d}|du rtd||jd< dS )zSet "START" or "END".r   Nz<You must set a TRIGGER before setting the RELATED parameter.r*   )r+   
ValueErrorr,   )r-   r2   r.   r/   r/   r0   r1      s   
c                   @  s*   e Zd ZU dZded< ded< ded< dS )zAlarm.TriggerszThe computed times of alarm triggers.

        start - triggers relative to the start of the Event or Todo (timedelta)

        end - triggers relative to the end of the Event or Todo (timedelta)

        absolute - triggers at a datetime in UTC
        ztuple[timedelta]startendztuple[datetime]absoluteN)__name__
__module____qualname____doc____annotations__r/   r/   r/   r0   Triggers   s
   
 	r<   c                 C  s   g }g }g }| j }|durFt|tr|| |}n| jdkr'|| |}n|| |}| j}|durFt| jD ]}||d |  q:| jt	|t	|t	|dS )a  The computed triggers of an Alarm.

        This takes the TRIGGER, DURATION and REPEAT properties into account.

        Here, we create an alarm that triggers 3 times before the start of the
        parent component:

        >>> from icalendar import Alarm
        >>> from datetime import timedelta
        >>> alarm = Alarm()
        >>> alarm.TRIGGER = timedelta(hours=-4)  # trigger 4 hours before START
        >>> alarm.DURATION = timedelta(hours=1)  # after 1 hour trigger again
        >>> alarm.REPEAT = 2  # trigger 2 more times
        >>> alarm.triggers.start == (timedelta(hours=-4),  timedelta(hours=-3),  timedelta(hours=-2))
        True
        >>> alarm.triggers.end
        ()
        >>> alarm.triggers.absolute
        ()
        Nr)   )r4   r5   r6   )
r   
isinstancer   appendr1   r    ranger!   r<   tuple)r-   r4   r5   r6   r.   addduration_r/   r/   r0   triggers   s(   




zAlarm.triggersr"   z
X-ALARMUID	attendeeslist[vCalAddress] | Noneconceptsr   description
str | Nonelinksr	   refidslist[str] | str | None
related_tor
   summaryuidstr | uuid.UUID | Nonec	          
        s0   t  j||||d}	||	_||	_||	_||	_|	S )a  Create a new alarm with all required properties.

        This creates a new Alarm in accordance with :rfc:`5545`.

        Parameters:
            attendees: The :attr:`attendees` of the alarm.
            concepts: The :attr:`~icalendar.Component.concepts` of the alarm.
            description: The :attr:`description` of the alarm.
            links: The :attr:`~icalendar.Component.links` of the alarm.
            refids: :attr:`~icalendar.Component.refids` of the alarm.
            related_to: :attr:`~icalendar.Component.related_to` of the alarm.
            summary: The :attr:`summary` of the alarm.
            uid: The :attr:`uid` of the alarm.

        Returns:
            :class:`Alarm`

        Raises:
            ~error.InvalidCalendar: If the content is not valid
                according to :rfc:`5545`.

        .. warning:: As time progresses, we will be stricter with the validation.
        )rK   rN   rL   rH   )supernewrO   rI   rP   rF   )
clsrF   rH   rI   rK   rL   rN   rO   rP   alarm	__class__r/   r0   rS   3  s   $z	Alarm.newexamplenamec                 C  s   |  td|S )z-Return the alarm example with the given name.alarms)	from_icalr   )rT   rY   r/   r/   r0   rX   c  s   zAlarm.example)r'   r(   )r2   r(   )NNNNNNNN)rF   rG   rH   r   rI   rJ   rK   r	   rL   rM   rN   r
   rO   rJ   rP   rQ   )rX   )rY   r(   r'   r   )(r7   r8   r9   r:   rY   required
singletons	inclusivemultipler   r!   propertyr   r   r   r    r   r$   r   r   r   r   r1   setterr   r<   rE   r   r   rP   r   rO   r   rI   r   rF   classmethodrS   rX   __classcell__r/   r/   rV   r0   r   !   sp    
 $
	
+/r   )!r:   
__future__r   r   r   r   typingr   r   icalendar.attrr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   icalendar.cal.componentr   icalendar.cal.examplesr   uuidicalendar.propr   r   __all__r/   r/   r/   r0   <module>   s    @  
J