

_V                 @   s   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)    )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] }	 | |	 j d  | |	 <| |	 s d | |	 <n  | |	 d k r| d 7} | d
 k r |	 } n  | | k r| } | } qq d } d } q W| d k r| | }
 |
 t |  k r[| 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_messagebest_doublecolon_startbest_doublecolon_lendoublecolon_startdoublecolon_lenZipv4_unpackedhextetsindexbest_doublecolon_endresult r   3/tmp/pip-build-ghmbqnp_/Django/django/utils/ipv6.pyclean_ipv6_address	   sH    

	
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   z%d.%d.%d.%d   r               r   )r   
startswithr   intr   )r   r   Zipv4_addressr   r   r   r    r   Z   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 } d |  k r  d S|  j d  d k r9 d Sd |  k rI d S|  j d  rh |  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 s5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_addressr   Fz::r   z:::r'   r"      r%   i  Tr   )
Zdjango.core.validatorsr+   countr(   endswithr   r   r   r)   
ValueError)r   r+   hextetr   r   r    r      s<    
!*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_ipr0   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)zDetermine 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    r2      s
    	"r2   N)Zdjango.core.exceptionsr   Zdjango.utils.six.movesr   Zdjango.utils.translationr   _r!   r   r   r   r   r2   r   r   r   r    <module>   s   P%@,