o
    .jy!                     @   sJ  d Z ddlZddlmZ ddlZddlZddlmZmZ ddl	Z	ddl
Z
ddlmZ ddlZdZdd ZG d	d
 d
Zdd Zejde	jde
jfddZG dd deZ		d&de
jdee	j dede
jfddZe ejdedddejdeddde e ejddd d!deded"efd#d$Z g d%Z!dS )'z7Bring calendars using X-WR-TIMEZONE into RFC 5545 form.    N)BytesIO)	vDDDTypes	vDDDLists)OptionalzX-WR-TIMEZONEc                 C   s(   t | t |kotdd t| |D S )z6Return wether all contents of two lists are identical.c                 s   s    | ]	\}}||u V  qd S N ).0e1e2r   r   B/home/thesage/.local/lib/python3.10/site-packages/x_wr_timezone.py	<genexpr>   s    zlist_is.<locals>.<genexpr>)lenallzip)l1l2r   r   r   list_is   s   (r   c                   @   sx   e Zd ZdZg dZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )CalendarWalkerzsI walk along the components and values of an icalendar object.

    The idea is the same as a visitor pattern.
    )DTSTARTDTENDRDATEzRECURRENCE-IDEXDATEc                 C   sz   |  D ]\}}|| |ur| |||  S qt|jt|ks#J t||jD ]\}}||ur:| |||  S q)|S )z~Check if an icalendar Component has changed and copy it if it has.

        atributes and subcomponents are put into the copy.)itemscopy_componentr   subcomponentsr   )self	component
attributesr   keyvaluenew_subcomponentold_subcomponentr   r   r   copy_if_changed(   s   zCalendarWalker.copy_if_changedc                 C   sL   |  }| D ]\}}|||< qt|jdksJ |D ]}|| q|S )zACreate a copy of the component with attributes and subcomponents.r   )copyr   r   r   add_component)r   r   r   r   r   r   subcomponentr   r   r   r   5   s   
zCalendarWalker.copy_componentc                 C   s@   g }|j D ]}t|tjjr| |}|| q| |i |S )zCWalk along the calendar and return the changed or identical object.)r   
isinstance	icalendarcalEvent
walk_eventappendr"   )r   calendarr   r%   r   r   r   walk?   s   

zCalendarWalker.walkc                 C   s@   i }| j D ]}||}|dur| |||< q| |||jS )z@Walk along the event and return the changed or identical object.N)VALUE_ATTRIBUTESget
walk_valuer"   r   )r   eventr   namer   r   r   r   r*   H   s   

zCalendarWalker.walk_eventc                 C      |S )z.Default method for walking along a value type.r   )r   r   r   r   r   walk_value_defaultQ      z!CalendarWalker.walk_value_defaultc                 C   s$   dt |j }t| || j}||S )zWalk along a value type.walk_value_)type__name__getattrr4   )r   r   r2   r-   r   r   r   r0   U   s   zCalendarWalker.walk_valuec                 C   s"   t t| j|}t||r|S |S )zWalk through a list of values.)listmapr0   r   )r   lvr   r   r   walk_value_list[   s   
zCalendarWalker.walk_value_listc                    s8   dd |j D } fdd|D }t||r|S t|S )Nc                 S   s   g | ]}|j qS r   )dt)r   dddr   r   r   
<listcomp>c   s    z7CalendarWalker.walk_value_vDDDLists.<locals>.<listcomp>c                    s   g | ]}  |qS r   )r0   )r   r?   r   r   r   rA   d   s    )dtsr   r   )r   r<   rC   new_dtsr   rB   r   walk_value_vDDDListsb   s
   
z#CalendarWalker.walk_value_vDDDListsc                 C   s"   |  |j}||ju r|S t|S )z"Walk along an icalendar value type)r0   r?   r   )r   r   r?   r   r   r   walk_value_vDDDTypesi   s   
z#CalendarWalker.walk_value_vDDDTypesc                 C   r3   )&Walk along a datetime.datetime object.r   r   r?   r   r   r   walk_value_datetimep   r5   z"CalendarWalker.walk_value_datetimec                 C   s    |  du rdS |   dkS )z0Return whether the time zone is a UTC time zone.NFUTC)tznameupperrH   r   r   r   is_UTCt   s   zCalendarWalker.is_UTCc                 C   s   |  d u S r   )rK   rH   r   r   r   is_Floatingz   s   zCalendarWalker.is_FloatingN)r8   
__module____qualname____doc__r.   r"   r   r-   r*   r4   r0   r>   rE   rF   rI   rM   rN   r   r   r   r   r       s    
		r   c                 C   s
   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tzinfor   r   r   is_pytz~   s   
rV   timezonereturnc                 C   s   t j| S )zZReturn a timezone component for the tzid and cache it.
    
    The result is cached.
    )r'   Timezonefrom_tzinfo)rW   r   r   r   get_timezone_component   s   r[   c                   @   s    e Zd ZdZdd Zdd ZdS )UTCChangingWalkerz/Changes the UTC time zone into a new time zone.c                 C   s
   || _ dS )z-Initialize the walker with the new time zone.N)new_timezone)r   rW   r   r   r   __init__   s   
zUTCChangingWalker.__init__c                 C   sH   |  |r|| jS | |r"t| jr| j|S |j| jdS |S )rG   rT   )rM   
astimezoner]   rN   rV   rR   replacerH   r   r   r   rI      s   


z%UTCChangingWalker.walk_value_datetimeN)r8   rO   rP   rQ   r^   rI   r   r   r   r   r\      s    r\   Fr,   add_timezone_componentc                 C   s   |du r
|  td}|durt|tjstt|}| }~ |durDt|}|	|}|rD|
 }|jdd |_|}|jdt| |S )a  Make a calendar that might use X-WR-TIMEZONE compatible with RFC 5545.

    Arguments:
    
        calendar: is an icalendar.Calendar object. It does not need to have
            the X-WR-TIMEZONE property but if it has, calendar  will be converted
            to conform to RFC 5545.
            
        timezone: an optional timezone argument if you want to override the
            existence of the actual X-WR-TIMEZONE property of the calendar.
            This can be a string like "Europe/Berlin" or "UTC" or a
            pytz.timezone or any other timezone accepted by the datetime module.
        
        add_timezone_component: whether to add a VTIMEZONE component to the result.
    Nr   )r/   X_WR_TIMEZONEr&   datetimerU   zoneinfoZoneInfostrr\   r-   r#   r   insertr[   )r,   rW   ra   resultwalkernew_calr   r   r   to_standard   s   
rk   in_filerb-)r7   defaultout_filewbz--add-timezone/--no-timezoneTz(Add a VTIMEZONE component to the result.)ro   helpadd_timezonec                 C   s.   t j|  }t||d}||  dS )a  x-wr-timezone converts ICSfiles with X-WR-TIMEZONE to use RFC 5545 instead.

    Convert input:

        cat in.ics | x-wr-timezone > out.ics
        wget -O- https://example.org/in.ics | x-wr-timezone > out.ics
        curl https://example.org/in.ics | x-wr-timezone > out.ics

    Convert files:

        x-wr-timezone in.ics out.ics

    By default, x-wr-timezone will add a VTIMEZONE component to the result.
    Use --no-vtimezone to remove it. (Added in v2.0.0)

    Get help:

        x-wr-timezone --help

    For bug reports, code and questions, visit the projet page:

        https://github.com/niccokunzmann/x-wr-timezone

    License: LPGLv3+
    )ra   r   )r'   Calendar	from_icalreadrk   writeto_ical)rl   rp   rs   r,   rj   r   r   r   main   s    ry   )ry   rk   r\   r   rb   r   r[   )NF)"rQ   	functoolsior   sysrd   icalendar.propr   r   rc   r'   typingr   clickrb   r   r   rV   cacherU   rY   r[   r\   rt   boolrk   commandargumentFileversion_optionhelp_optionoptionry   __all__r   r   r   r   <module>   sH   ^	
$" 