U
    j:                     @  s  d Z ddlmZ ddlZddlmZ ddlmZmZ ddlm	Z	 ddlm
Z
 ddlZdd	 Zd
d ZdBddZdCddZedZedZedZedZedZedZdd ZdDddZedZdEdd ZdFd#d$ZdGd%d&ZG d'd( d(eZd)d* Zd+d, Zed-Z d.d.d/d0d1Z!ed2Z"d.d.d/d3d4Z#d5d6 Z$G d7d8 d8e%Z&G d9d: d:e'Z(d8d:d;d<d=d(d>d?d@d d	d*ddd&d$d4d1dAdd6d,ddgZ)dS )Ha  This module parses and generates contentlines as defined in RFC 5545
(iCalendar), but will probably work for other MIME types with similar syntax.
Eg. RFC 2426 (vCard)

It is stupid in the sense that it treats the content purely as strings. No type
conversion is attempted.
    )annotationsN)CaselessDict)DEFAULT_ENCODING	ICAL_TYPE)SEQUENCE_TYPES)
to_unicodec                 C  sF   t | ttfst| ddddddddd	d
dd
S )z8Format value according to iCalendar TEXT escaping rules.\N
\\\;\;,\,
\n
isinstancestrbytesAssertionErrorreplacetext r   4/tmp/pip-unpacked-wheel-g40nyxg1/icalendar/parser.pyescape_char   s$         r   c                 C  s   t | ttfstt | trP| ddddddddddd	d
S t | tr| ddddddddddddS d S )Nr   r   r   r	   r   r   r   r   r   r
   s   \Ns   \n   
   
s   \,   ,s   \;   ;s   \\   \r   r   r   r   r   unescape_char!   sJ    
     
     r"   K   
 c              	     s   t tstdkstzd W n ttfk
r@   Y n,X | fddtdt d D S g }d}D ]:}t|t	}||7 }| kr|
| |}|
| qxd|S )a  Make a string folded as defined in RFC5545
    Lines of text SHOULD NOT be longer than 75 octets, excluding the line
    break.  Long content lines SHOULD be split into a multiple line
    representations using a line "folding" technique.  That is, a long
    line can be split between any two characters by inserting a CRLF
    immediately followed by a single linear white-space character (i.e.,
    SPACE or HTAB).
    r	   asciic                 3  s"   | ]}||  d   V  qdS )   Nr   ).0ilimitliner   r   	<genexpr>J   s    zfoldline.<locals>.<genexpr>r   r&    )r   r   r   encodeUnicodeEncodeErrorUnicodeDecodeErrorjoinrangelenr   append)r+   r*   Zfold_sepZ	ret_charsZ
byte_countcharZchar_byte_lenr   r)   r   foldline8   s&    	
r6   Fc                 C  sL   t | trttt| |dS t | tr6tt| |dS tt|  t	S )zReturns a parameter value.always_quote)
r   r   q_joinmaprfc_6868_escaper   dquoteto_icaldecoder   )valuer8   r   r   r   param_value_   s
    

r@   z[\w.-]+z[ -
-",:;]z
[ -
-"]s
   (?
)+[ 	]z
(?
)+[ 	]z\r?\nc                 C  s2   t | }t|dkr&| |d kr&d S t| d S )Nr&   r   )NAMEfindallr3   
ValueError)namematchr   r   r   validate_tokenu   s    
rF   Tc                 C  s"   |rt nt}|| rt| d S N)QUNSAFE_CHARUNSAFE_CHARrB   rC   )r?   quotedZ	validatorr   r   r   validate_param_value|   s    
rK   u   [,;:’]c                 C  s*   |  dd} t| s|r&d|  dS | S )z;Enclose parameter values containing [,;:] in double quotes."')r   QUOTABLEsearch)valr8   r   r   r   r<      s    r<   r   c           
      C  s   |dkr| gS g }d}t | }d}d}t| D ]n\}}	|	dkrD| }|sr|	|krr|| ||  |d }|d7 }|d |ks||kr.|| |d   qq.|S )zDSplits a string on char, taking double (q)uotes into considderation.r   rL   r&   N)r3   	enumerater4   )
stsepmaxsplitresultcursorlengthZinquotesplitsr(   chr   r   r   q_split   s$    r[   c                   s   |  fdd| D S )z9Joins a list on sep, quoting strings with QUOTABLE chars.c                 3  s   | ]}t | d V  qdS )r7   N)r<   )r'   Zitmr7   r   r   r,      s     zq_join.<locals>.<genexpr>r1   )lstrT   r8   r   r7   r   r9      s    r9   c                   @  s<   e Zd ZdZdZddiZdd Zddd	ZedddZ	dS )
ParameterszParser and generator of Property parameter strings. It knows nothing of
    datatypes. Its main concern is textual structure.
    )ZALTREPzDELEGATED-FROMzDELEGATED-TOZDIRZMEMBERzSENT-BYz	X-ADDRESSzX-TITLEZCNz 'c                 C  s   |   S )zpIn RFC 5545 keys are called parameters, so this is to be consitent
        with the naming conventions.
        )keysselfr   r   r   params   s    zParameters.paramsTc           	        s   g }t |  }|r|  |D ]|\} | }| j| }|| jkpb|obt fdd|D }t |d}t	|t
r|t}||td |  q d|S )Nc                 3  s   | ]}| kV  qd S rG   r   )r'   cr?   r   r   r,      s     z%Parameters.to_ical.<locals>.<genexpr>r7      =r    )listitemssortupper
quote_alsogetalways_quotedanyr@   r   r   r.   r   r4   r1   )	ra   sortedrV   rg   keyZ	upper_keyZcheck_quoteable_charactersr8   Zquoted_valuer   rd   r   r=      s     


zParameters.to_icalFc           
      C  s"  |  }t |dD ]
}zt |ddd\}}t| g }t |dD ]p}|dr~|dr~|d}t|dd |t| q@t|d	d |r|t|  q@|t| q@|s|||< n"t	|dkr|d
 ||< n|||< W q t
k
r }	 zt
|d|	 W 5 d}	~	X Y qX q|S )z2Parses the parameter format from ical text format.r   =r&   )rU   r   rL   T)rJ   Fr   z" is not a valid parameter string: N)r[   rF   
startswithendswithstriprK   r4   rfc_6868_unescaperi   r3   rC   )
clsrS   strictrV   paramro   rP   valsvexcr   r   r   	from_ical   s.    

&zParameters.from_icalN)T)F)
__name__
__module____qualname____doc__rl   rj   rb   r=   classmethodr{   r   r   r   r   r^      s    
r^   c                 C  s$   |  dd dd dd ddS )	Nr   %2Cz\:%3Ar   %3Br   %5Cr   rP   r   r   r   escape_string  s       r   c                 C  s$   |  dd dd dd ddS )	Nr   r   r   :r   r   r   r
   r   r   r   r   r   unescape_string"  s       r   z\^\^|\^n|\^'r   )r@   returnc                   s"   dt jdd t fdd| S )zTake care of :rfc:`6868` unescaping.

    - ^^ -> ^
    - ^n -> system specific newline
    - ^' -> "
    - ^ with others stay intact
    ^rL   )^^^n^'c                   s     | d| dS Nr   rk   groupmreplacementsr   r   <lambda>;      z#rfc_6868_unescape.<locals>.<lambda>)oslinesepRFC_6868_UNESCAPE_REGEXsubr@   r   r   r   rt   .  s
    	rt   z\^|\r\n|\r|\n|"c                   s$   dddddd t  fdd| S )zXTake care of :rfc:`6868` escaping.

    - ^ -> ^^
    - " -> ^'
    - newline -> ^n
    r   r   r   )r   r	   r   rL   c                   s     | d| dS r   r   r   r   r   r   r   N  r   z!rfc_6868_escape.<locals>.<lambda>)RFC_6868_ESCAPE_REGEXr   r   r   r   r   r;   @  s    r;   c                 C  s$   t | trdd | D S t| S d S )Nc                 S  s   g | ]}t |qS r   )r   )r'   sr   r   r   
<listcomp>R  s     z+unescape_list_or_string.<locals>.<listcomp>)r   rf   r   r   r   r   r   unescape_list_or_stringP  s    
r   c                      sZ   e Zd ZdZdef fdd	Zeddddd	d
Zdd ZedddZ	dd Z
  ZS )ContentlinezWA content line is basically a string that can be folded and parsed into
    parts.
    Fc                   s4   t ||d}d|kstdt | |}||_|S )N)encodingr	   z;Content line can not contain unescaped new line characters.)r   r   super__new__rv   )ru   r?   rv   r   ra   	__class__r   r   r   `  s    
zContentline.__new__Tr   r^   )rD   rb   c                 C  s   t |tstt|dr"| }nddlm} || }t|}t|}|rvt|j|d}| | d| d| S | | d| S )z!Turn a parts into a content line.r=   r   )vText)rn   r   r   )r   r^   r   hasattrr=   Zicalendar.propr   r   )ru   rD   rb   valuesrn   r   r   r   r   
from_partsi  s    

zContentline.from_partsc              
   C  s6  zt | }d}d}d}t|D ]:\}}|sJ|dkr:|s:|}|dkrJ|sJ|}|dkr| }qt|d| }|svtdt| |s|d }|r|d |krtdtj||d | | jd	}td
d t|	 D }t||d d }	|||	fW S  tk
r0 }
 ztd|  d|
 |
W 5 d}
~
X Y nX dS )z@Split the content line up into (name, parameters, values) parts.NFz:;r   rL   zKey name is requiredr&   zInvalid content linerv   c                 s  s"   | ]\}}t |t|fV  qd S rG   )r   r   )r'   ro   r?   r   r   r   r,     s   z$Contentline.parts.<locals>.<genexpr>z.Content line could not be parsed into parts: 'z': )
r   rR   r   rC   rF   r^   r{   rv   iterrg   )ra   rS   Z
name_splitZvalue_splitZ	in_quotesr(   rZ   rD   rb   r   rz   r   r   r   parts~  sH     
zContentline.partsc                 C  s   t |}| td||dS )zAUnfold the content lines in an iCalendar into long content lines.r-   r   )r   uFOLDr   )ru   Zicalrv   r   r   r   r{     s    zContentline.from_icalc                 C  s   t | tS )zXLong content lines are folded so they are less than 75 characters
        wide.
        )r6   r.   r   r`   r   r   r   r=     s    zContentline.to_ical)T)F)r|   r}   r~   r   r   r   r   r   r   r{   r=   __classcell__r   r   r   r   r   [  s   	%r   c                   @  s$   e Zd ZdZdd Zedd ZdS )ContentlineszI assume that iCalendar files generally are a few kilobytes in size.
    Then this should be efficient. for Huge files, an iterator should probably
    be used instead.
    c                 C  s   d dd | D d S )zSimply join self.r   c                 s  s   | ]}|r|  V  qd S rG   )r=   r'   r+   r   r   r   r,     s      z'Contentlines.to_ical.<locals>.<genexpr>r\   r`   r   r   r   r=     s    zContentlines.to_icalc                 C  s^   t |}z4td|}| dd t|D }|d |W S  tk
rX   tdY nX dS )z#Parses a string into content lines.r-   c                 s  s   | ]}|rt |V  qd S rG   )r   r   r   r   r   r,     s      z)Contentlines.from_ical.<locals>.<genexpr>z&Expected StringType with content linesN)r   r   r   NEWLINEsplitr4   	ExceptionrC   )ru   rS   Zunfoldedlinesr   r   r   r{     s    
zContentlines.from_icalN)r|   r}   r~   r   r=   r   r{   r   r   r   r   r     s   r   FOLDrA   r   rH   rN   rI   r   )r#   r$   )F)T)F)r   rQ   )r   F)*r   
__future__r   r   Zicalendar.caselessdictr   Zicalendar.parser_toolsr   r   r   r   rer   r"   r6   r@   compilerA   rI   rH   r   r   r   rF   rK   rN   r<   r[   r9   r^   r   r   r   rt   r   r;   r   r   r   rf   r   __all__r   r   r   r   <module>   st   
'











j
	

V