
    i                        d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddd	d
dZ
e G d d                      Zd,dZd-dZd.dZd/dZd0dZd1dZd2d!Z	 	 d3d4d)Zd5d+ZdS )6a  
Calendar operations - Sans-I/O business logic for Calendar objects.

This module contains pure functions for Calendar operations like
component class detection, sync token generation, and result processing.
Both sync and async clients use these same functions.
    )annotationsN)	dataclass)AnyquoteEventTodoJournalFreeBusy)zBEGIN:VEVENTzBEGIN:VTODOzBEGIN:VJOURNALzBEGIN:VFREEBUSYc                  F    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   d
S )CalendarObjectInfozCInformation about a calendar object extracted from server response.strurl
str | Nonedataetagcomponent_typedictextra_propsN)__name__
__module____qualname____doc____annotations__     Y/root/projects/butler/venv/lib/python3.11/site-packages/caldav/operations/calendar_ops.pyr   r      sQ         MMHHHr   r   r   r   returnr   c                    |                      d          D ].}|                                }|t          v rt          |         c S /dS )z
    Detect the component type (Event, Todo, etc.) from iCalendar string data.

    Args:
        data: iCalendar data as string

    Returns:
        Component type name ("Event", "Todo", "Journal", "FreeBusy") or None
    
N)splitstripCOMPONENT_CLASS_MAP)r   lines     r   "_detect_component_type_from_stringr%   $   sS     

4   - -zz||&&&&t,,,, '4r   ical_objr   c                    ddl }|j        d|j        d|j        d|j        di}t          | d          sdS t          | j                  sdS | j        D ]}|j        |v r||j                 c S dS )z
    Detect the component type from an icalendar object.

    Args:
        ical_obj: icalendar.Calendar or similar object with subcomponents

    Returns:
        Component type name ("Event", "Todo", "Journal", "FreeBusy") or None
    r   Nr   r	   r
   r   subcomponents)		icalendarr   r	   r
   r   hasattrlenr(   	__class__)r&   r)   	ical2namescs       r   %_detect_component_type_from_icalendarr/   5   s      	9J	I 8_-- tx%&& t$ + +<9$$R\**** % 4r   c                    | dS t          | d          rt          |           S t          | d          rt          |           S dS )z
    Detect the component type from iCalendar data (string or object).

    Args:
        data: iCalendar data as string, bytes, or icalendar object

    Returns:
        Component type name ("Event", "Todo", "Journal", "FreeBusy") or None
    Nr!   r(   )r*   r%   r/   )r   s    r   _detect_component_typer1   U   sW     |t tW 81$777 t_%% ;4T:::4r   etags_and_urlslist[tuple[str | None, str]]c                t   g }| D ]L\  }}|r#|                     t          |                     *|                     t          |                     M|                                 d                    |          }t	          j        |                                d                                          }d| S )am  
    Generate a fake sync token for servers without sync support.

    Uses a hash of all ETags/URLs to detect changes. This allows clients
    to use the sync token API even when the server doesn't support it.

    Args:
        etags_and_urls: List of (etag, url) tuples. ETag may be None.

    Returns:
        A fake sync token string prefixed with "fake-"
    |F)usedforsecurityfake-)appendr   sortjoinhashlibmd5encode	hexdigest)r2   partsr   r   combined
hash_values         r   _generate_fake_sync_tokenrB   m   s     E# # #	c 	#LLT#### LLS""""	JJLLLxxHX__..FFFPPRRJ:r   tokenboolc                ^    | duo)t          | t                    o|                     d          S )z
    Check if a sync token is a fake one generated by the client.

    Args:
        token: Sync token string

    Returns:
        True if this is a fake sync token
    Nr7   )
isinstancer   
startswith)rC   s    r   _is_fake_sync_tokenrH      s1     UE3!7!7UE<L<LW<U<UUr   
result_url
parent_urlc                ,    d| v r| S t          |           S )aL  
    Normalize a URL from search/report results.

    Handles quoting for relative URLs and ensures proper joining with parent.

    Args:
        result_url: URL from server response (may be relative or absolute)
        parent_url: Parent calendar URL

    Returns:
        Normalized URL string ready for joining with parent
    z://r   )rI   rJ   s     r   _normalize_result_urlrL      s%     
 r   calendar_urlc                b    |                      d          }|                     d          }||k    S )a  
    Check if a result URL should be skipped because it's the calendar itself.

    iCloud and some other servers return the calendar URL along with
    calendar item URLs. This function helps filter those out.

    Args:
        result_url: URL from server response
        calendar_url: The calendar's URL

    Returns:
        True if this URL should be skipped (it's the calendar itself)
    /)rstrip)rI   rM   result_normalizedcalendar_normalizeds       r   $_should_skip_calendar_self_referencerS      s:     #))#..&--c22  333r   ,{urn:ietf:params:xml:ns:caldav}calendar-data{DAV:}getetagresultsr   calendar_data_tagetag_taglist[CalendarObjectInfo]c           
     l   g }|                     d          }|                                 D ]\  }}t          ||          r|                    |d          }|                    |          }	t          |          }
t          ||          }|                    t          |||	|
|                     |S )ax  
    Process REPORT response results into CalendarObjectInfo objects.

    Args:
        results: Dict mapping href -> properties dict
        calendar_url: URL of the calendar (to filter out self-references)
        calendar_data_tag: XML tag for calendar data property
        etag_tag: XML tag for etag property

    Returns:
        List of CalendarObjectInfo objects
    rO   N)r   r   r   r   r   )	rP   itemsrS   popgetr1   rL   r8   r   )rV   rM   rW   rX   objectscalendar_url_normalizedhrefpropsr   r   r   normalized_urls               r   _process_report_resultsrc      s    $ G*11#66}} 
 
e/6MNN 	 yy*D11 yy"" 055 /t\BB"-!  	
 	
 	
 	
 Nr   	object_idc                    t          |                               d          } t          t          |                    }|                    d          s|dz  }|  d| S )a   
    Build a URL for a calendar object from calendar URL and object ID.

    Args:
        calendar_url: URL of the parent calendar
        object_id: ID of the calendar object (typically UID.ics)

    Returns:
        Full URL for the calendar object
    rO   z.ics)r   rP   r   endswith)rM   rd   s     r   _build_calendar_object_urlrg      sf     |$$++C00Lc)nn%%If%% V	((Y(((r   )r   r   r   r   )r&   r   r   r   )r   r   r   r   )r2   r3   r   r   )rC   r   r   rD   )rI   r   rJ   r   r   r   )rI   r   rM   r   r   rD   )rT   rU   )
rV   r   rM   r   rW   r   rX   r   r   rY   )rM   r   rd   r   r   r   )r   
__future__r   r;   dataclassesr   typingr   urllib.parser   r#   r   r%   r/   r1   rB   rH   rL   rS   rc   rg   r   r   r   <module>rl      s    # " " " " "  ! ! ! ! ! !             !	             "   @   0       6
V 
V 
V 
V   *4 4 4 42 L#	0 0 0 0 0f) ) ) ) ) )r   