
    iO                        d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZ dd	l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 erddlm Z  ddl!m"Z"m#Z#  G d d          Z$dgZ%dS )z%Calculation of series based on rrule.    )annotationsN)TYPE_CHECKING	GeneratorSequence)rrulerrulesetrrulestr)	vDDDTypes)NEGATIVE_RRULE_COUNT_REGEX)BadRuleStringFormat)
Occurrence)
compare_greaterconvert_to_dateconvert_to_datetimeget_anyis_dateis_pytz
is_pytz_dtnormalize_pytzto_recurrence_idswith_highest_sequence)ComponentAdapter)RecurrenceIDTimec                      e Zd ZdZ	 	 d$d%dZ G d d          Z G d d          Zd&dZd Ze	d'd            Z
e	d(d            Zd)dZd*dZd+d!Ze	d"             Zd# ZdS ),SerieszABase class for components that result in a series of occurrences.Nadapterr   startTime | Noneend Time | None | datetime.timedeltareturnr   c                2    t          |||| j                  S )z'A way to override the occurrence class.sequence)r   r%   )selfr   r   r    s       ]/root/projects/butler/venv/lib/python3.11/site-packages/recurring_ical_events/series/rrule.py
occurrencezSeries.occurrence#   s     '5#FFFF    c                      e Zd ZU dZ e            Zded<    e            Zded<   i Zded<   dZ	ddZ
edd            ZddZdZ ej        d           ej        d          fZg ZdS )Series.NoRecurrencez6A strategy to deal with not having a core with rrules.zset[RecurrenceID]check_exdates_datetimezset[datetime.date]check_exdates_datezdict[RecurrenceID, Time]replace_endsr   r   stopr(   type[Occurrence]corer   r"   r   c                     t          d          Nz"This code should never be reached.NotImplementedErrorr&   r   r0   r(   r2   s        r'   as_occurrencez!Series.NoRecurrence.as_occurrence4   s     &&JKKKr)   c                     t          d          r4   r5   r&   s    r'   r2   zSeries.NoRecurrence.core=   s    %&JKKKr)   
span_start	span_stopGenerator[Time, None, None]c              #     K   g E d{V  dS )zNo repetition.N )r&   r;   r<   s      r'   rrule_betweenz!Series.NoRecurrence.rrule_betweenA   s       MMMMMMMMMr)   Fr   N
r   r   r0   r   r(   r1   r2   r   r"   r   )r"   r   )r;   r   r<   r   r"   r=   )__name__
__module____qualname____doc__setr,   __annotations__r-   r.   r%   r8   propertyr2   r@   has_coredatetime	timedeltaextend_query_span_by
componentsr?   r)   r'   NoRecurrencer+   ,   s         DD47CEE9999146666133333	L 	L 	L 	L 
	L 	L 	L 
	L	 	 	 	  2 21 5 57Ix7I!7L7LM


r)   rN   c                      e Zd ZdZdZed"d            Zd#dZed$d
            Zd%dZ	d&dZ
d'dZd Zd(dZd Zd)dZed*d             Zd!S )+Series.RecurrenceRulesz6A strategy if we have an actual core with recurrences.Tr"   intc                    | j         j        S )z#The sequence of the code component.)r2   r%   r:   s    r'   r%   zSeries.RecurrenceRules.sequenceR   s     9%%r)   r2   r   c                   || _         | j         j        x| _        | _        | j         j        x| _        | _        t                      | _        t                      | _        t                      | _        t                      | _	        i | _
        | j         j        D ]l}| j                            |           | j                            t          |                     t          |          r| j                            |           m| j         j	        D ]}t          |t                     rz| j	                            |d                    t          |d                   D ]C}t          |d         t"          j                  r|d         n|d         |d         z
  | j
        |<   D| j	                            |           |                                  t)          d          }d |_        |g| _        d }| j         j        D ]V}|                     |          }| j                            |           |j        r|rt3          |j        |          r|j        }W| j        D ]}| j                            |           | j	        D ]}|                    |           |rt3          | j        |          s|                    | j                   d S d S )Nr      T)cache)r2   r   original_startr    original_endrF   exdatesr,   r-   rdatesr.   addupdater   r   
isinstancetuplerJ   rK   make_all_dates_comparabler   untilrrulescreate_rule_with_startappendr   rdate)	r&   r2   exdaterc   recurrence_idrule_set
last_untilrrule_stringrules	            r'   __init__zSeries.RecurrenceRules.__init__W   s   DI/3y>DJ,+/9=8DHt(&)eeDL=@UUD':=%%D#%(UUDK   )+ 8 8  (((+223DV3L3LMMM6?? 8+//777) + +eU++ +KOOE!H---):58)D)D    *%(H4FGG5E!HH!&qE!H!4 )-88 KOOE**** **,,,  d+++H!HN#*DK&*J $	 0 , ,22<@@""4(((: ,",&5dj*&M&M, "&J, 8 8+//7777 & &u%%%% +_TZ%L%L +tz*****+ +r)   -tuple[datetime.timedelta, datetime.timedelta]c                    | j         j        S )zAThe extension of the time span we need for this component's core.)r2   rL   r:   s    r'   rL   z+Series.RecurrenceRules.extend_query_span_by   s     911r)   rule_stringstrr   c                   	 |                      |          S # t          $ r |                    d          }t          |          dk    rt	          d|          d|d                             d          }|dk    rt          |d                   }|d         d|         }| j        r|dd         }nS| j        |dd         }nAt          |          dk    r|d	z  }t          |          d
k    rt	          d|          d|dz  }|d         |d         |d         z   dz   |z   }|                      |          cY S w xY w)zHelper to create an rrule from a rule_string

            The rrule is starting at the start of the component.
            Since the creation is a bit more complex,
            this function handles special cases.
            ;UNTIL=   zUNTIL parameter is missingNrT   ;r/      T000000   z UNTIL parameter has a bad formatZr   )r	   
ValueErrorsplitlenr   findis_all_datestzinfo)r&   rm   	rule_listdate_end_indexuntil_stringnew_rule_strings         r'   ra   z-Series.RecurrenceRules.create_rule_with_start   s   %6}}[111 #6 #6 #6
 (--i88	y>>Q&&-4k   "+1!2!23!7!7!R''%(1%6%6N(|O^O<$ (#/#3LL[(#/#4LL <((A--$	1<((B..1> #$ !C'LaLl>??34  ##   }}_55555G#6s    D#D=<D=c                T   t          j        d|          }t          || j        d          }||_        |                     |          x|_        }t          | j        j                  r?|j        r8|	                    |j        t          j        d          z             }||_        |S )z1Return an rrulestr with a start. This might fail. T)dtstartrU   rT   hours)r_   )r   subr	   r   string_get_rrule_untilr_   r   r|   replacerJ   rK   )r&   rm   ri   r_   s       r'   r	   zSeries.RecurrenceRules.rrulestr   s    48[IIKK4HHHD%DK!%!6!6t!<!<<DJtz()) #dj # ||$*x7IPQ7R7R7R*R|SS"
Kr)   None | Timec                Z   |j                             d          }t          |          dk    rdS t          |          dk    rt          d|          |d                             d          }|dk    rt          |d                   }|d         d|         }t          j        |          S )z9Return the UNTIL datetime of the rrule or None if absent.rp   rT   Nrq   zThere should be only one UNTILrr   r/   )r   rx   ry   r   rz   r
   	from_ical)r&   r   r}   r~   r   s        r'   r   z'Series.RecurrenceRules._get_rrule_until   s    **955I9~~""t9~~"")*JERRR&q\..s33N##!$Yq\!2!2$Q<8L&|444r)   c                    d _          j         j        g j         j        }t          d |D                         _        |D ]1}t          |t          j                  r|j         |j          _          n2t           j         j                    _        t           j         j                    _         fd j        D              _         fd j        D              _        dS )a  Make sure we can use all dates with eachother.

            Dates may be mixed and we have many of them.
            - date
            - datetime without timezone
            - datetime with timezone
            These three are not comparable but can be converted.
            Nc              3  J   K   | ]}t          |t          j                  V  d S N)r\   rJ   ).0dates     r'   	<genexpr>zCSeries.RecurrenceRules.make_all_dates_comparable.<locals>.<genexpr>   s@       ( (8<
4!233( ( ( ( ( (r)   c                :    h | ]}t          |j                  S r?   r   r|   )r   rc   r&   s     r'   	<setcomp>zCSeries.RecurrenceRules.make_all_dates_comparable.<locals>.<setcomp>   s3       <A#E4;77  r)   c                :    h | ]}t          |j                  S r?   r   )r   rd   r&   s     r'   r   zCSeries.RecurrenceRules.make_all_dates_comparable.<locals>.<setcomp>   s3       =C#FDK88  r)   )
r|   r   r    rX   rY   anyr{   r\   rJ   r   )r&   datesr   s   `  r'   r^   z0Series.RecurrenceRules.make_all_dates_comparable   s    DKZGDLG4;GE$' ( (@E( ( ( % % !D   dH$566 4;;R"&+DKE,TZEEDJ*48T[AADH   EI[  DK   GK|  DLLLr)   r;   r   r<   Generator[Time]c              #    K   t          || j                  }t          || j                  }t          | j                  rJt          |t	          j        d          z
            }t          |t	          j        d          z             }| j        D ]z}|                    ||d          D ]_}t          |          r.|j        	                    |
                    d                    }|j        t          ||j                  s|V  `{dS )z<Recalculate the rrules so that minor mistakes are corrected.rT   r   T)incN)r|   )r   r|   r   r   rJ   rK   r`   betweenr   localizer   r_   r   )r&   r;   r<   span_start_dtspan_stop_dtri   r   s          r'   r@   z$Series.RecurrenceRules.rrule_between   s&      0
DKHHM.y$+FFL t{##  .!H$6Q$?$?$??! !  . 8#5A#>#>#>>     $ $!\\-4\PP $ $E!%(( R % 5 5emm4m6P6P Q Q z)
1S1S)#$$ $r)   c                    t          | j        t          j                  s.t          | j        t          j                  st	          |          S |S )a:  Convert a date back if this is possible.

            Dates may get converted to datetimes to make calculations possible.
            This reverts the process where possible so that Repetitions end
            up with the type (date/datetime) that was specified in the icalendar
            component.
            )r\   rV   rJ   rW   r   )r&   r   s     r'   convert_to_original_typez/Series.RecurrenceRules.convert_to_original_type  sT     #X%6  - !! - 't,,,Kr)   r   r0   r(   r1   r   c                h     |||                      |          |                      |                    S )z0Return this as an occurrence at a specific time.)r   r7   s        r'   r8   z$Series.RecurrenceRules.as_occurrence(  s=     :--e44--d33  r)   list[ComponentAdapter]c                    | j         gS )z.The components in this recurrence calculation.)r2   r:   s    r'   rM   z!Series.RecurrenceRules.components6  s     I;r)   N)r"   rQ   )r2   r   )r"   rk   )rm   rn   r"   r   )r"   r   )r"   r   r;   r   r<   r   r"   r   rA   r"   r   )rB   rC   rD   rE   rI   rH   r%   rj   rL   ra   r	   r   r^   r@   r   r8   rM   r?   r)   r'   RecurrenceRulesrP   M   s       DD		& 	& 	& 
	&9	+ 9	+ 9	+ 9	+v 
	2 	2 	2 
	2,	6 ,	6 ,	6 ,	6\	 	 	 		5 	5 	5 	5	 	 	8	$ 	$ 	$ 	$6	 	 	"	 	 	 	 
	 	 	 
	 	 	r)   r   rM   Sequence[ComponentAdapter]c                    t          |          dk    rt          d          i | _        g | _        |d         j        | _        d}|D ]}|                                rd|j        }|D ]2}t          | j        	                    |          |          | j        |<   3|j        r | j        
                    |d                    zt          ||          }t          | j                                                  | _        ~||                                 n|                     |          | _        | j                                         t%          d | j        D                       | _        |                                  dS )z5Create an component which may have repetitions in it.r   z*No components given to calculate a series.Nc              3  $   K   | ]}|j         V  d S r   r$   )r   	components     r'   r   z"Series.__init__.<locals>.<genexpr>^  s%      PP9I.PPPPPPr)   )ry   rw   recurrence_id_to_modificationthis_and_futureuid_uidis_modificationrecurrence_idsr   getrb   rF   valuesmodificationsrN   r   
recurrencesortmaxrM   r%   compute_span_extension)r&   rM   r2   r   r   re   s         r'   rj   zSeries.__init__;  s   z??aIJJJ  	*  "qM%	(,# 	> 	>I((** >!*!9%3  M- >BB=QQ%  6}EE , C(//q0ABBB,T9==47.55775
 5
 #'<DT5I5I$5O5O 	 	!!###PPPPPPP##%%%%%r)   c                    | j         j        \  | _        | _        | j        D ]@}|j        \  }}t          || j                  | _        t          || j                  | _        AdS )zFCompute how much to extend the span for the rrule to cover all events.N)r   rL   _subtract_from_start_add_to_stopthis_and_future_componentsr   )r&   r   subtract_from_startadd_to_stops       r'   r   zSeries.compute_span_extensiona  s     O0 	5!4#4 6 	D 	DG/6/K,(+#T%>) )D% !$K1B C CD	D 	Dr)   r   c                D    | j         j        t          | j                  z   S )zAll the components in this sequence.

        Components with the same UID might not occur if the SEQUENCE
        number suggests that they are obsolete.
        )r   rM   listr   r:   s    r'   rM   zSeries.componentsm  s     )D1C,D,DDDr)   Generator[ComponentAdapter]c              #  p   K   | j         j        r| j         j        V  | j        D ]}| j        |         V  dS )z,All components that influence future events.N)r   rI   r2   r   r   )r&   re   s     r'   r   z!Series.this_and_future_componentsv  s]       ?# 	'/&&&&!1 	D 	DM4]CCCCC	D 	Dr)   re   r   c                Z    | j         j        }| j        D ]}||k     r| j        |         } |S )zGet the component which contains all information for the recurrence id.

        This concerns this modifications that have RANGE=THISANDFUTURE set.
        )r   r2   r   r   )r&   re   r   modification_ids       r'   get_component_for_recurrence_idz&Series.get_component_for_recurrence_id~  sC     O(	#3 	 	O.. >O		r)   r;   r   r<   r   c              #     K   t          || j        z
            }t          || j        z             }| j                            ||          E d{V  dS )z7Modify the rrule generation span and yield recurrences.N)r   r   r   r   r@   )r&   r;   r<   expanded_startexpanded_stops        r'   r@   zSeries.rrule_between  sx      '
T5N(NOO&y43D'DEE?00
 
 	
 	
 	
 	
 	
 	
 	
 	
 	
r)   Generator[Occurrence]c           	   #    K   t                      }t                      }|                     ||          D ]`}t          |          }||v s7t          |          | j        j        v s| j        j        t          |          z  rNt          | j        || j        j	                  }|| j        j	        u r|
                    |           |                     |d                   }t          ||j        z             }	t          |	t          | j        j        ||j                  z             }
| j                            |	|
| j        |          }n0||v r|
                    |           |                     |          }|                    ||          r|V  b| j        D ]j}||v s!| j        j        t          |j                  z  r(|                    ||          r,|
                    |           |                     |          V  kdS )zwComponents between the start (inclusive) and end (exclusive).

        The result does not need to be ordered.
        r   N)rF   r@   r   r   r   r-   r,   r   r   r2   rZ   r   r   move_recurrences_byr.   durationr8   r(   
is_in_spanr   r   )r&   r;   r<   returned_startsreturned_modificationsr   r   r   r   occurrence_startoccurrence_endr(   modifications                r'   r   zSeries.between  sK     
 &)UU8; ''
I>> &	! &	!E.u55N(("5))T_-OOO?9C<O<OO P (/2NDODX) )G $/...##E*** !@@PQARSS	#1%):W2W#X#X !/$4&!* " " "_::$ndoy 


 444&**7333!__W55
$$Z;; !     . 
	4 
	4L  666?9l1223 7 &&z9== 4&**<888ool33333
	4 
	4r)   c                    | j         S )z$The UID that identifies this series.)r   r:   s    r'   r   z
Series.uid  s     yr)   c                \    d| j         j         d| j         dt          | j                   dS )zA string representation.<z uid=z modifications:>)	__class__rB   r   ry   r   r:   s    r'   __repr__zSeries.__repr__  sP    H' H Hdh H H !CDDH H H	
r)   )NN)r   r   r   r   r    r!   r"   r   )rM   r   r   )r"   r   )re   r   r"   r   r   )r;   r   r<   r   r"   r   )rB   rC   rD   rE   r(   rN   r   rj   r   rH   rM   r   r   r@   r   r   r   r?   r)   r'   r   r       sp       KK
 "04	G G G G G       Bl l l l l l l l\$& $& $& $&L
D 
D 
D E E E XE D D D XD    
 
 
 
:4 :4 :4 :4x   X
 
 
 
 
r)   r   )&rE   
__future__r   rJ   typingr   r   r   dateutil.rruler   r   r	   icalendar.propr
   recurring_ical_events.constantsr   recurring_ical_events.errorsr    recurring_ical_events.occurrencer   recurring_ical_events.utilr   r   r   r   r   r   r   r   r   r   (recurring_ical_events.adapters.componentr   recurring_ical_events.typesr   r   r   ___all__r?   r)   r'   <module>r      s   + + " " " " " "  5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 $ $ $ $ $ $ F F F F F F < < < < < < 7 7 7 7 7 7                         ?IIIIII>>>>>>>>}
 }
 }
 }
 }
 }
 }
 }
@ :r)   