3
‡ŒðiíC  ã               @   s  d 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 ddd	d
gZddl	Z	ddl
Z
dZdZdZddddddddddddddddddd d!d"d#d$d%gZd&d'd(d)d*d+d,gZddddd>d?d@dAdBdCdDdEdFdGd3œZd4d	„ Zd5d6„ Zd7d„ Zd8d„ Zd9d
„ ZG d:d;„ d;eƒZG d<d=„ d=eƒZdS )HzcEmail address parsing code.

Lifted directly from rfc822.py.  This should eventually be rewritten.
é    )Úunicode_literals)Úprint_function)Údivision)Úabsolute_import)ÚintÚ	mktime_tzÚ	parsedateÚparsedate_tzÚquoteNú Ú z, ÚjanÚfebÚmarÚaprÚmayÚjunÚjulÚaugÚsepÚoctÚnovÚdecÚjanuaryÚfebruaryÚmarchÚaprilÚjuneÚjulyÚaugustÚ	septemberÚoctoberÚnovemberÚdecemberÚmonÚtueÚwedÚthuÚfriÚsatÚsuni�  i,  iô  iX  i¼  i   )ÚUTÚUTCÚGMTÚZÚASTÚADTÚESTÚEDTÚCSTÚCDTÚMSTÚMDTÚPSTÚPDTc             C   s,   t | ƒ}|sdS |d dkr$d|d< t|ƒS )zQConvert a date string to a time tuple.

    Accounts for military timezones.
    Né	   r   )Ú_parsedate_tzÚtuple)ÚdataÚres© r>   úC/tmp/pip-build-6m2fasei/future/future/backports/email/_parseaddr.pyr	   3   s    c             C   s¾  | sdS | j ƒ } | d jdƒs.| d jƒ tkr6| d= n.| d jdƒ}|dkrd| d |d d… | d< t| ƒdkrš| d j dƒ}t|ƒdkrš|| dd…  } t| ƒdk�r | d }|jdƒ}|dkrÌ|jdƒ}|dkrö|d|… ||d… g| dd…< n
| jd	ƒ t| ƒd
k �rdS | dd
… } | \}}}}}|jƒ }|tk�rZ||jƒ  }}|tk�rZdS tj	|ƒd }|dk�rz|d8 }|d dk�r”|dd… }|jdƒ}|dk�r²|| }}|d dk�rÌ|dd… }|d j
ƒ �sä|| }}|d dk�rþ|dd… }|j dƒ}t|ƒdk�r$|\}	}
d}n~t|ƒdk�r>|\}	}
}ndt|ƒdk�ržd|d k�rž|d j dƒ}t|ƒdk�r„|\}	}
d}nt|ƒdk�r¢|\}	}
}ndS y,t|ƒ}t|ƒ}t|	ƒ}	t|
ƒ}
t|ƒ}W n tk
�rä   dS X |dk �r|dk�r|d7 }n|d7 }d}|jƒ }|tk�r,t| }n>yt|ƒ}W n tk
�rN   Y nX |dk�rj|jdƒ�rjd}|�r¦|dk �r†d}| }nd}||d d |d d   }||||	|
|ddd|g
S )a†  Convert date to extended time tuple.

    The last (additional) element is the time zone offset in seconds, except if
    the timezone was specified as -0000.  In that case the last element is
    None.  This indicates a UTC timestamp that explicitly declaims knowledge of
    the source timezone, as opposed to a +0000 timestamp that indicates the
    source timezone really was UTC.

    Nr   ú,é   é   ú-é   ú+r   é   é   ú:é   Ú0Ú.éd   éD   il  iÐ  i  é<   éÿÿÿÿrO   rO   rO   rO   rO   rO   rO   rO   )ÚsplitÚendswithÚlowerÚ	_daynamesÚrfindÚlenÚfindÚappendÚ_monthnamesÚindexÚisdigitr   Ú
ValueErrorÚupperÚ
_timezonesÚ
startswith)r<   ÚiÚstuffÚsÚddÚmmÚyyÚtmÚtzÚthhÚtmmÚtssÚtzoffsetÚtzsignr>   r>   r?   r:   ?   s¬    


"














r:   c             C   s&   t | ƒ}t|tƒr|dd… S |S dS )z&Convert a time string to a time tuple.Nr9   )r	   Ú
isinstancer;   )r<   Útr>   r>   r?   r   ´   s    
c             C   s<   | d dkr"t j| dd… d ƒS tj| ƒ}|| d  S dS )zETurn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.r9   Né   rA   rO   )rO   )ÚtimeÚmktimeÚcalendarÚtimegm)r<   rm   r>   r>   r?   r   ½   s    
c             C   s   | j ddƒj ddƒS )zøPrepare string to be used in a quoted string.

    Turns backslash and double quote characters into quoted pairs.  These
    are the only characters that need to be quoted inside a quoted string.
    Does not add the surrounding double quotes.
    ú\z\\ú"z\")Úreplace)Ústrr>   r>   r?   r
   Ç   s    c               @   s|   e Zd Z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d„Zdd„ Zdd„ Zdd„ Zddd„Zdd„ ZdS ) ÚAddrlistClassa  Address parser class by Ben Escoto.

    To understand what this class does, it helps to have a copy of RFC 2822 in
    front of you.

    Note: this class interface is deprecated and may be removed in the future.
    Use email.utils.AddressList instead.
    c             C   sZ   d| _ d| _d| _d| _| j| j | _| j | j | j | _| jjddƒ| _|| _g | _	dS )zƒInitialize a new instance.

        `field' is an unparsed address header field, containing
        one or more addresses.
        z()<>@,:;."[]r   z 	z
rK   r   N)
ÚspecialsÚposÚLWSÚCRÚFWSÚatomendsru   Ú
phraseendsÚfieldÚcommentlist)Úselfr   r>   r>   r?   Ú__init__Û   s    zAddrlistClass.__init__c             C   s�   g }x€| j t| jƒk r„| j| j  | jd kr^| j| j  dkrN|j| j| j  ƒ |  j d7  _ q| j| j  dkr€| jj| jƒ ƒ qP qW tj|ƒS )z&Skip white space and extract comments.z
rA   ú()	ry   rU   r   rz   rW   r€   Ú
getcommentÚEMPTYSTRINGÚjoin)r�   Úwslistr>   r>   r?   Úgotonextî   s    zAddrlistClass.gotonextc             C   s>   g }x4| j t| jƒk r8| jƒ }|r,||7 }q|jdƒ qW |S )zVParse all addresses.

        Returns a list containing all of the addresses.
        r   )r   r   )ry   rU   r   Ú
getaddressrW   )r�   ÚresultÚadr>   r>   r?   Úgetaddrlistü   s    
zAddrlistClass.getaddrlistc             C   sö  g | _ | jƒ  | j}| j }| jƒ }| jƒ  g }| jt| jƒkr\|rXtj| j ƒ|d fg}�n\| j| j dkr–|| _|| _ | jƒ }tj| j ƒ|fg}�n"| j| j dk�rg }t| jƒ}|  jd7  _xò| jt| jƒk �r| jƒ  | j|k oø| j| j dk�r|  jd7  _P || j	ƒ  }qÆW nš| j| j dk�rx| j
ƒ }| j �rftj|ƒd dj| j ƒ d	 |fg}ntj|ƒ|fg}n@|�r–tj| j ƒ|d fg}n"| j| j | jk�r¸|  jd7  _| jƒ  | jt| jƒk �rò| j| j d
k�rò|  jd7  _|S )zParse the next address.r   z.@rH   rA   ú;ú<z (r   ú)r@   )r€   rˆ   ry   ÚgetphraselistrU   r   ÚSPACEr†   Úgetaddrspecr‰   Úgetrouteaddrrx   )r�   ÚoldposÚoldclÚplistÚ
returnlistÚaddrspecÚfieldlenÚ	routeaddrr>   r>   r?   r‰   
  sL    
&$zAddrlistClass.getaddressc             C   sä   | j | j dkrdS d}|  jd7  _| jƒ  d}x¬| jt| j ƒk rÞ|rV| jƒ  d}n~| j | j dkrx|  jd7  _P n\| j | j dkrœ|  jd7  _d}n8| j | j d	kr¼|  jd7  _n| jƒ }|  jd7  _P | jƒ  q4W |S )
z�Parse a route address (Return-path value).

        This method just skips all the route stuff and returns the addrspec.
        rŽ   NFrA   r   ú>ú@TrH   )r   ry   rˆ   rU   Ú	getdomainr’   )r�   ÚexpectrouteÚadlistr>   r>   r?   r“   E  s.    zAddrlistClass.getrouteaddrc             C   sN  g }| j ƒ  xà| jt| jƒk rìd}| j| j dkrj|rL|d jƒ  rL|jƒ  |jdƒ |  jd7  _d}nf| j| j dkr’|jdt| jƒ ƒ ƒ n>| j| j | j	krÂ|r¾|d	 jƒ  r¾|jƒ  P n|j| j
ƒ ƒ | j ƒ }|r|r|j|ƒ qW | jt| jƒk�s| j| j dk�rtj|ƒS |jdƒ |  jd7  _| j ƒ  tj|ƒ| jƒ  S )
zParse an RFC 2822 addr-spec.TrK   rA   Frt   z"%s"rœ   rO   rO   )rˆ   ry   rU   r   ÚstripÚpoprW   r
   Úgetquoter}   Úgetatomr…   r†   r�   )r�   ÚaslistÚpreserve_wsÚwsr>   r>   r?   r’   e  s4    
$

zAddrlistClass.getaddrspecc             C   sÖ   g }xÆ| j t| jƒk rÊ| j| j  | jkr8|  j d7  _ q| j| j  dkrZ| jj| jƒ ƒ q| j| j  dkrz|j| jƒ ƒ q| j| j  dkr¤|  j d7  _ |jdƒ q| j| j  | jkrºP q|j| j	ƒ ƒ qW t
j|ƒS )z-Get the complete domain name from an address.rA   rƒ   ú[rK   )ry   rU   r   rz   r€   rW   r„   Úgetdomainliteralr}   r£   r…   r†   )r�   Úsdlistr>   r>   r?   r�   †  s    zAddrlistClass.getdomainTc             C   sæ   | j | j |krdS dg}d}|  jd7  _x®| jt| j ƒk rÚ|rZ|j| j | j ƒ d}np| j | j |kr||  jd7  _P nN|r¢| j | j dkr¢|j| jƒ ƒ q.n(| j | j dkr¸d}n|j| j | j ƒ |  jd7  _q.W tj|ƒS )aæ  Parse a header fragment delimited by special characters.

        `beginchar' is the start character for the fragment.
        If self is not looking at an instance of `beginchar' then
        getdelimited returns the empty string.

        `endchars' is a sequence of allowable end-delimiting characters.
        Parsing stops when one of these is encountered.

        If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed
        within the parsed fragment.
        r   FrA   rƒ   rs   T)r   ry   rU   rW   r„   r…   r†   )r�   Ú	begincharÚendcharsÚallowcommentsÚslistr
   r>   r>   r?   Úgetdelimited™  s(    zAddrlistClass.getdelimitedc             C   s   | j dddƒS )z1Get a quote-delimited fragment from self's field.rt   z"F)r®   )r�   r>   r>   r?   r¢   ¾  s    zAddrlistClass.getquotec             C   s   | j dddƒS )z7Get a parenthesis-delimited fragment from self's field.rƒ   z)T)r®   )r�   r>   r>   r?   r„   Â  s    zAddrlistClass.getcommentc             C   s   d| j dddƒ S )z!Parse an RFC 2822 domain-literal.z[%s]r§   z]F)r®   )r�   r>   r>   r?   r¨   Æ  s    zAddrlistClass.getdomainliteralNc             C   sh   dg}|dkr| j }xH| jt| jƒk r\| j| j |kr:P n|j| j| j ƒ |  jd7  _qW tj|ƒS )a  Parse an RFC 2822 atom.

        Optional atomends specifies a different set of end token delimiters
        (the default is to use self.atomends).  This is used e.g. in
        getphraselist() since phrase endings must not include the `.' (which
        is legal in phrases).r   NrA   )r}   ry   rU   r   rW   r…   r†   )r�   r}   Úatomlistr>   r>   r?   r£   Ê  s    zAddrlistClass.getatomc             C   sª   g }x | j t| jƒk r¤| j| j  | jkr8|  j d7  _ q| j| j  dkrX|j| jƒ ƒ q| j| j  dkrz| jj| jƒ ƒ q| j| j  | jkr�P q|j| j	| jƒƒ qW |S )zýParse a sequence of RFC 2822 phrases.

        A phrase is a sequence of words, which are in turn either RFC 2822
        atoms or quoted-strings.  Phrases are canonicalized by squeezing all
        runs of continuous whitespace into one space.
        rA   rt   rƒ   )
ry   rU   r   r|   rW   r¢   r€   r„   r~   r£   )r�   r–   r>   r>   r?   r�   Þ  s    zAddrlistClass.getphraselist)T)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r‚   rˆ   rŒ   r‰   r“   r’   r�   r®   r¢   r„   r¨   r£   r�   r>   r>   r>   r?   rw   Ñ   s   ; !
%
rw   c               @   sH   e Zd Z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 )ÚAddressListz@An AddressList encapsulates a list of parsed RFC 2822 addresses.c             C   s&   t j| |ƒ |r| jƒ | _ng | _d S )N)rw   r‚   rŒ   Úaddresslist)r�   r   r>   r>   r?   r‚   ÷  s    zAddressList.__init__c             C   s
   t | jƒS )N)rU   rµ   )r�   r>   r>   r?   Ú__len__þ  s    zAddressList.__len__c             C   sB   t d ƒ}| jd d … |_x$|jD ]}|| jkr |jj|ƒ q W |S )N)r´   rµ   rW   )r�   ÚotherÚnewaddrÚxr>   r>   r?   Ú__add__  s    
zAddressList.__add__c             C   s*   x$|j D ]}|| j kr| j j|ƒ qW | S )N)rµ   rW   )r�   r·   r¹   r>   r>   r?   Ú__iadd__
  s    
zAddressList.__iadd__c             C   s2   t d ƒ}x$| jD ]}||jkr|jj|ƒ qW |S )N)r´   rµ   rW   )r�   r·   r¸   r¹   r>   r>   r?   Ú__sub__  s
    
zAddressList.__sub__c             C   s*   x$|j D ]}|| j kr| j j|ƒ qW | S )N)rµ   Úremove)r�   r·   r¹   r>   r>   r?   Ú__isub__  s    
zAddressList.__isub__c             C   s
   | j | S )N)rµ   )r�   rY   r>   r>   r?   Ú__getitem__   s    zAddressList.__getitem__N)r°   r±   r²   r³   r‚   r¶   rº   r»   r¼   r¾   r¿   r>   r>   r>   r?   r´   õ  s   	r´   ipþÿÿiÔþÿÿiþÿÿipþÿÿi¨ýÿÿiþÿÿiDýÿÿi¨ýÿÿiàüÿÿiDýÿÿ)r³   Ú
__future__r   r   r   r   Zfuture.builtinsr   Ú__all__ro   rq   r‘   r…   Ú
COMMASPACErX   rS   r]   r	   r:   r   r   r
   Úobjectrw   r´   r>   r>   r>   r?   Ú<module>   sB   

u	

  &