î
ªÍ XÏ  ã               @   s”   d  d l  Z  d  d l m Z d  d l m Z d  d l m Z d e d ƒ d d „ Z d	 d
 „  Z	 d d „  Z
 d d „  Z d d „  Z d d „  Z d S)é    N)ÚValidationError)Úrange)Úugettext_lazyFz!This is not a valid IPv6 address.c             C   s¹  d	 } d } d
 } d } t  |  ƒ s9 t | d d ƒ‚ n  t |  ƒ }  t |  ƒ }  | rp t |  ƒ } | rp | Sn  |  j d ƒ } x´ t t | ƒ ƒ D]  }	 d | |	 k rÂ | |	 j d ƒ | |	 <n  | |	 sÙ d | |	 <n  | |	 d k r&| d 7} | d k r|	 } n  | | k r2| } | } q2q’ d } d } q’ W| d k r | | }
 |
 t | ƒ k rn| d g 7} n  d g | | |
 … <| d k r d g | } q n  d j	 | ƒ } | j
 ƒ  S)aU  
    Cleans an IPv6 address string.

    Validity is checked by calling is_valid_ipv6_address() - if an
    invalid address is passed, ValidationError is raised.

    Replaces the longest continuous zero-sequence with "::" and
    removes leading zeroes and makes sure all hextets are lowercase.

    Args:
        ip_str: A valid IPv6 address.
        unpack_ipv4: if an IPv4-mapped address is found,
        return the plain IPv4 address (default=False).
        error_message: An error message used in the ValidationError.

    Returns:
        A compressed IPv6 address, or the same value
    é   r   ÚcodeÚinvalidú:Ú.Ú0Ú éÿÿÿÿr   r   r   )Úis_valid_ipv6_addressr   Ú_explode_shorthand_ip_stringÚ_sanitize_ipv4_mappingÚ_unpack_ipv4Úsplitr   ÚlenÚlstripÚjoinÚlower)Úip_strZunpack_ipv4Úerror_messageZbest_doublecolon_startZbest_doublecolon_lenZdoublecolon_startZdoublecolon_lenZipv4_unpackedÚhextetsÚindexZbest_doublecolon_endÚresult© r   ú?/home/ubuntu/projects/ifolica/build/django/django/utils/ipv6.pyÚclean_ipv6_address   sJ    

	
r   c             C   sÙ   |  j  ƒ  j d ƒ s |  S|  j d ƒ } d | d k r< |  Sd t | d d d … d	 ƒ t | d d d
 … d	 ƒ t | d d d … d	 ƒ t | d d d
 … d	 ƒ f } d j | d d … ƒ } | d | 7} | S)a?  
    Sanitize IPv4 mapping in an expanded IPv6 address.

    This converts ::ffff:0a0a:0a0a to ::ffff:10.10.10.10.
    If there is nothing to sanitize, returns an unchanged
    string.

    Args:
        ip_str: A string, the expanded IPv6 address.

    Returns:
        The sanitized output string, if applicable.
    z0000:0000:0000:0000:0000:ffff:r   r	   r   z%d.%d.%d.%dé   r   é   é   é   é   r   )r   Ú
startswithr   Úintr   )r   r   Zipv4_addressr   r   r   r   r   ]   s    !r   c             C   s-   |  j  ƒ  j d ƒ s d S|  j d d ƒ d S)ag  
    Unpack an IPv4 address that was mapped in a compressed IPv6 address.

    This converts 0000:0000:0000:0000:0000:ffff:10.10.10.10 to 10.10.10.10.
    If there is nothing to sanitize, returns None.

    Args:
        ip_str: A string, the expanded IPv6 address.

    Returns:
        The unpacked IPv4 address, or None if there was nothing to unpack.
    z0000:0000:0000:0000:0000:ffff:Nr   r   )r   r#   Úrsplit)r   r   r   r   r   ‚   s    r   c             C   sÔ  d d l  m } t j d ƒ } | j |  ƒ s2 d Sd |  k rB d S|  j d ƒ d k r[ d Sd |  k rk d S|  j d ƒ rŠ |  j d ƒ s© |  j d ƒ r­ |  j d ƒ r­ d S|  j d ƒ d	 k rÆ d Sd |  k r|  j d ƒ d	 k r|  j d
 ƒ d k rd Sn  t |  ƒ }  x¾ |  j	 d ƒ D]­ } | j d
 ƒ d k r|  j	 d ƒ d | k sWd Sy | | ƒ WqÌt
 k
 r}d SYqÌXqy2 t | d ƒ d k  s®t | d ƒ d k r²d SWqt k
 rËd SYqXqWd S)z¬
    Ensure we have a valid IPv6 address.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A boolean, True if this is a valid IPv6 address.
    r   )Úvalidate_ipv4_addressz^[0-9a-fA-F:.]+$Fr   z::r   z:::r"   r	   é   r    iÿÿ  Tr   )Zdjango.core.validatorsr&   ÚreÚcompileÚmatchÚcountr#   Úendswithr   r   r   r$   Ú
ValueError)r   r&   Z
symbols_reÚhextetr   r   r   r   •   sB    
!*r   c             C   s<  t  |  ƒ s |  Sg  } |  j d ƒ } d |  j d ƒ d k rG d } n d } t | ƒ d k rä t | d j d ƒ ƒ t | d j d ƒ ƒ } | d j d ƒ } x% t | | ƒ D] } | j d ƒ q³ W| | d j d ƒ 7} n |  j d ƒ } g  } x3 | D]+ } | j d	 d
 t | ƒ | j ƒ  ƒ q Wd j | ƒ S)zœ
    Expand a shortened IPv6 address.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A string, the expanded IPv6 address.
    z::r	   r   r   r"   é   r   Z0000r
   r!   r   )Ú_is_shorthand_ipr   r   r   Úappendr   r   )r   Znew_ipr.   Zfill_toÚsepÚ__Zret_ipr   r   r   r   Ù   s$    
	0)r   c             C   sC   |  j  d ƒ d k r d St d d „  |  j d ƒ Dƒ ƒ r? d Sd S)z¥Determine if the address is shortened.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A boolean, True if the address is shortened.
    z::r   Tc             s   s!   |  ] } t  | ƒ d  k  Vq d S)r!   N)r   )Ú.0Úxr   r   r   ú	<genexpr>  s    z#_is_shorthand_ip.<locals>.<genexpr>r   F)r+   Úanyr   )r   r   r   r   r0     s
    	"r0   )r(   Zdjango.core.exceptionsr   Zdjango.utils.six.movesr   Zdjango.utils.translationr   Ú_r   r   r   r   r   r0   r   r   r   r   Ú<module>   s   Q%D,