
    F2j                       d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	m
Z
 ddlmZ erddlmZ ddlmZmZmZ dBdZdCdZdDdZdEdZdFdZdFdZdFdZdGdZdHdZdId"Z	 dJdKd)ZdLd,ZdMd.ZdFd/Z dNd3Z!dOd5Z"dPd9Z#dQdRd@Z$g dAZ%dS )SzUtility functions.    )annotationsN)wraps)TYPE_CHECKINGCallableOptionalSequence)PeriodEndBeforeStart)ComponentAdapter)RecurrenceIDsTime	Timestampdtdatetime.datetimereturnr   c                *    |                                  S )z#Return the time stamp of a datetime)	timestamp)r   s    b/home/thesage/.hermes/hermes-agent/venv/lib/python3.11/site-packages/recurring_ical_events/util.pyr   r      s    <<>>    dater   datetime.datec                L    t          j        | j        | j        | j                  S )z%Converts a date or datetime to a date)datetimer   yearmonthday)r   s    r   convert_to_dater      s    =DJ999r   tzinfodatetime.tzinfo | Timec                "    t          | d          S )zWhether the time zone requires localize() and normalize().

    pytz requires these funtions to be used in order to correctly use the
    time zones after operations.
    localize)hasattrr   s    r   is_pytzr#      s     6:&&&r   timec                X    t          |           r| j                            |           S | S )zAWe have to normalize the time after a calculation if we use pytz.)
is_pytz_dtr   	normalizer$   s    r   normalize_pytzr)   #   s-    $ +{$$T***Kr   boolc                l    t          | t          j                  ot          | t          j                   S )z*Whether this is a date and not a datetime.)
isinstancer   r   r(   s    r   is_dater-   *   s)    dHM**V:dHDU3V3V/VVr   c                6    t          | t          j                  S )z*Whether this is a datetime and not a date.)r,   r   r(   s    r   is_datetimer/   /   s    dH-...r   c                2    t          |           o| j        duS )z*Whether this date/datetime has a timezone.N)r/   r   r(   s    r   has_timezoner1   4   s    t8D!88r   Optional[datetime.tzinfo]c                x   t          |           r%t          j        | j        | j        | j                  } t          | t          j                  rk| j        =|:t          |          r|                    |           S | 	                    |          S n%|#t          |           	                    d          S | S | S )a*  Converts a date to a datetime.

    Dates are converted to datetimes with tzinfo.
    Datetimes loose their timezone if tzinfo is None.
    Datetimes receive tzinfo as a timezone if they do not have a timezone.
    Datetimes retain their timezone if they have one already (tzinfo is not None).
    Nr"   )r-   r   r   r   r   r,   r   r#   r    replacer)   )r   r   s     r   convert_to_datetimer5   9   s     t}} B DJAA$)** ;!6?? 1!??4000||6|222 " ^!$''//t/<<<Kr   +tuple[datetime.datetime, datetime.datetime]c                    t          |           r| n|                     dddd          }||t          j        d          z   fS )zConvert the datetime to a start and end date in between it occurs.

    Returns:
        (start, end) where start <= dt < end
    r   )hourmicrosecondminutesecond   )days)r-   r4   r   	timedelta)r   starts     r   convert_to_date_ranger@   Q   sK     "++XBB2::1!AVW:#X#XE%(,!444444r   datesSequence[Time]
list[Time]c                    dd}| D ]+}t          |          sd}t          |          r	|j         n,|r| S fd| D             S )zEMake an list or tuple of dates comparable.

    Returns an list.
    NTFc                0    g | ]}t          |          S  )r5   ).0r   r   s     r   
<listcomp>z#make_comparable.<locals>.<listcomp>j   s$    @@@$f--@@@r   )r-   r1   r   )rA   	all_datesr   r   s      @r   make_comparablerJ   [   su    
 FI  t}} 	ID!!  @@@@%@@@@r   F
span_start	span_stopevent_start
event_stop
comparablec                6   |st          | |||f          \  } }}}||k    rt          d| d| d||          | |k    rt          d|  d| d| |          ||k    r| |k    r|| k    S | |cxk    o|k     nc S | |k    r|| cxk    o|k     nc S ||k     o| |k     S )a{  Return whether an event should is included within a time span.

    - span_start and span_stop define the time span
    - event_start and event_stop define the event time
    - comparable indicates whether the dates can be compared.
        You can set it to True if you are sure you have timezones and
        date/datetime correctly or used make_comparable() before.

    Note that the stops are exlusive but the starts are inclusive.

    This is an essential function of the module. It should be tested in
    test/test_time_span_contains_event.py.

    This raises a PeriodEndBeforeStart exception if a start is after an end.
    z+the event must start before it ends(start: z end: )z/the time span must start before it ends(start: )rJ   r	   )rK   rL   rM   rN   rO   s        r   time_span_contains_eventrR   m   sM   ,  
9HK<:
 :
6
I{J Z"<&< <.8< < < 
 
 	
 I":%: :-6: : : 
 
 	
 j  ""*,,[4444944444Yj5555:55555">zJ'>>r   date1date2c                6    t          | |f          \  } }| |k    S )zCCompare two dates if date1 > date2 and make them comparable before.rJ   rS   rT   s     r   compare_greaterrX      s!    "E5>22LE55=r   intc                D    t          | |f          \  } }| |k    | |k     z
  S )zCompare two dates, like cmp().

    Returns
    -------
        -1 if date1 < date2
         0 if date1 = date2
         1 if date1 > date2

    rV   rW   s     r   cmpr[      s,     #E5>22LE5EMeem,,r   c                ^    t          | t          j                  ot          | j                  S )zWhether the time requires localize() and normalize().

    pytz requires these funtions to be used in order to correctly use the
    time zones after operations.
    )r,   r   r#   r   r(   s    r   r&   r&      s&     dH-..G74;3G3GGr   funcr   propertyc                     d j          t                      t          t                     d fd                        }|S )z&Cache the property value for speed up._cached_selfobjectc                p    | j                                       }|u r |           x| j         <   }|S N)__dict__get)ra   valuer]   name	not_founds     r   cached_propertyz(cached_property.<locals>.cached_property   sE     !!$	22I*.$t**4DM$%r   )ra   rb   )__name__rb   r^   r   )r]   rj   rh   ri   s   ` @@r   rj   rj      sg    %dm%%DI
4[[       [ X r   r   c                   t          | t          j                  st          | d          fS | j        | fS |                     t          j        j                                      d          |                     d          fS )zConvert the time to a recurrence id so it can be hashed and recognized.

    The first value should be used to identify a component as it is a datetime in UTC.
    The other values can be used to look the component up.
    Nr"   )r,   r   r5   r   
astimezonetimezoneutcr4   r(   s    r   to_recurrence_idsrp      s|     dH-.. 2#D$//11{w)-..66d6CCD!! r   adapter1ComponentAdapter | Noneadapter2c                (    t          | |d           S )z)Return the one with the highest sequence.c                    | dn| j         S )Ng    _)sequence)adapters    r   <lambda>z'with_highest_sequence.<locals>.<lambda>   s    W_EE':J r   )key)max)rq   rs   s     r   with_highest_sequencer{      s'     JJ   r   
dictionarydictkeysSequence[object]defaultrb   c                @    |}|D ]}|                      ||          }|S )z)Get any item from the keys and return it.)rf   )r|   r~   r   resultry   s        r   get_anyr      s0    F - -V,,Mr   )r	   r[   r@   r5   r   r1   r-   r/   r#   r&   rJ   r)   rR   rp   r{   )r   r   r   r   )r   r   r   r   )r   r   )r$   r   r   r   )r$   r   r   r*   )r   r   r   r2   r   r   )r   r   r   r6   )rA   rB   r   rC   )F)rK   r   rL   r   rM   r   rN   r   rO   r*   r   r*   )rS   r   rT   r   r   r*   )rS   r   rT   r   r   rY   )r]   r   r   r^   )r$   r   r   r   )rq   rr   rs   rr   rd   )r|   r}   r~   r   r   rb   )&__doc__
__future__r   r   	functoolsr   typingr   r   r   r   recurring_ical_events.errorsr	   (recurring_ical_events.adapters.componentr
   recurring_ical_events.typesr   r   r   r   r   r#   r)   r-   r/   r1   r5   r@   rJ   rR   rX   r[   r&   rj   rp   r{   r   __all__rF   r   r   <module>r      s@     " " " " " "        > > > > > > > > > > > > = = = = = = KIIIIIIJJJJJJJJJJ   
: : : :
' ' ' '   W W W W
/ / / /
9 9 9 9
   05 5 5 5A A A A. 2? 2? 2? 2? 2?j   - - - - H H H H       $         r   