U
    d/D                     @   s  d dl Z d dlmZmZmZmZmZmZmZm	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m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mZ  d dl!m"Z"m#Z#m$Z$m%Z%m&Z& d dl'm(Z( dd e)dD Z*G dd dZ+G dd dZ,G dd dZ-G dd de&j.Z.eee/f Z0ee/ee0 f Z1eee0e1f  Z2G dd de.ej3Z4G dd de.ej5Z6G dd deZ7e7j8G dd  d ej9Z:e7j8G d!d" d"e:Z;G d#d$ d$ej<Z=e7j8G d%d& d&e=Z>e7j8G d'd( d(e>Z?e7j8G d)d* d*e=Z@e7j8G d+d, d,e@ZAe7j8G d-d. d.e=ZBe7j8G d/d0 d0eBZCe7j8G d1d2 d2e=ZDe7j8G d3d4 d4eDZEeFd5d6 e$jG dS )7    N)AnyCallableIterableOptionalTupleTypeUnioncast)parse)forms)FieldListFilter)checks
exceptions)lookups)BLANK_CHOICE_DASH	CharField)	force_str)lazy)escape)	Countries	countriesfiltersioc_datawidgets)settingsc                 C   s   i | ]}|j | qS  )nameload).0epr   r   ;/tmp/pip-unpacked-wheel-dnjn05s9/django_countries/fields.py
<dictcomp>   s    r!   zdjango_countries.Countryc                   @   s4   e Zd ZddgZdd Zdd Zdd Zd	d
 ZdS )TemporaryEscapecountryoriginal_escapec                 C   s
   || _ d S Nr#   )selfr#   r   r   r    __init__   s    zTemporaryEscape.__init__c                 C   s   | j jS r%   )r#   _escaper'   r   r   r    __bool__   s    zTemporaryEscape.__bool__c                 C   s   | j j| _d| j _d S )NT)r#   r)   r$   r*   r   r   r    	__enter__!   s    
zTemporaryEscape.__enter__c                 C   s   | j | j_d S r%   )r$   r#   r)   )r'   typevalue	tracebackr   r   r    __exit__%   s    zTemporaryEscape.__exit__N)__name__
__module____qualname__	__slots__r(   r+   r,   r0   r   r   r   r    r"      s
   r"   c                   @   s*  e Zd Zd0eee eee dddZdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zedd Zedd ZedddZeedddZeedddZeee ddd Zeee dd!d"Zeedd#d$Zeedd%d&Zed'd( Zed1d*d+Zed,d- Zd.d/ ZdS )2CountryNcoder6   flag_urlstr_attrcustom_countriesc                 C   s:   || _ d| _|| _|tkrd }|| _| j|p2|| _d S )NF)r8   r)   	_str_attrr   r:   Zalpha2r6   )r'   r6   r8   r9   r:   r   r   r    r(   *   s    zCountry.__init__c                 C   s   t t| | jpdS N )r   getattrr;   r*   r   r   r    __str__<   s    zCountry.__str__c                 C   s   t | jp
dt |pdkS r<   )r   r6   r'   otherr   r   r    __eq__?   s    zCountry.__eq__c                 C   s   |  | S r%   )rB   r@   r   r   r    __ne__B   s    zCountry.__ne__c                 C   s   t t| S r%   )hashr   r*   r   r   r    __hash__E   s    zCountry.__hash__c                 C   s`   d| j g}| jd k	r*|d| j | jdkrF|d| j | jj dd| dS )Nzcode=z	flag_url=r6   z	str_attr=(z, ))r6   r8   appendr;   	__class__r1   join)r'   argsr   r   r    __repr__H   s    

zCountry.__repr__c                 C   s
   t | jS r%   )boolr6   r*   r   r   r    r+   P   s    zCountry.__bool__c                 C   s   t t| S r%   )lenr   r*   r   r   r    __len__S   s    zCountry.__len__c                 C   s
   | j ptS r%   )r:   r   r*   r   r   r    r   V   s    zCountry.countriesc                 C   s   t | S r%   )r"   r*   r   r   r    r   Z   s    zCountry.escape)returnc                 C   s   | j rt|S |S r%   )r   escape_html)r'   textr   r   r    maybe_escape^   s    zCountry.maybe_escapec                 C   s   |  | j| jS r%   )rS   r   r   r6   r*   r   r   r    r   a   s    zCountry.namec                 C   s   | j | jS r%   )r   alpha3r6   r*   r   r   r    rT   e   s    zCountry.alpha3c                 C   s   | j | jS r%   r   numericr6   r*   r   r   r    rV   i   s    zCountry.numericc                 C   s   | j j| jddS )NT)ZpaddedrU   r*   r   r   r    numeric_paddedm   s    zCountry.numeric_paddedc                 C   sT   | j s
dS | j}|d krtj}|j| j | j  d}|s<dS ttj|}| 	|S )Nr=   )Z
code_upperr6   )
r6   r8   r   ZCOUNTRIES_FLAG_URLformatlowerurlparseurljoinZ
STATIC_URLrS   )r'   r8   urlr   r   r    flagq   s    zCountry.flagc                 C   s,   | j s
dS t| j  \}}d| d| S )a  
        Output the css classes needed to display an HTML element as a flag
        sprite.

        Requires the use of 'flags/sprite.css' or 'flags/sprite-hq.css'.
        Usage example::

            <i class="{{ ctry.flag_css }}" aria-label="{{ ctry.code }}></i>
        r=   zflag-sprite flag-z flag-_)r6   listrY   )r'   xyr   r   r    flag_css~   s    zCountry.flag_cssc                    s>   | j s
dS d  fdd| j  D }t|d t|d  S )a  
        Generate a unicode flag for the given country.

        The logic for how these are determined can be found at:

        https://en.wikipedia.org/wiki/Regional_Indicator_Symbol

        Currently, these glyphs appear to only be supported on OS X and iOS.
        r=   i c                    s   g | ]}t |  qS r   )ord)r   r_   ZOFFSETr   r    
<listcomp>   s     z(Country.unicode_flag.<locals>.<listcomp>r      )r6   upperchr)r'   Zpointsr   rc   r    unicode_flag   s
    zCountry.unicode_flagr=   c                 C   s&   t j| d}|dkrd S t||dS )Nr=   )r8   )r   Z
IOC_TO_ISOgetr5   )ioc_coder8   r6   r   r   r    country_from_ioc   s    zCountry.country_from_iocc                 C   s   | j | jS r%   )r   rj   r6   r*   r   r   r    rj      s    zCountry.ioc_codec                 C   s   |t krt | | S t d S r%   )
EXTENSIONSAttributeError)r'   attrr   r   r    __getattr__   s    zCountry.__getattr__)Nr6   N)r=   )r1   r2   r3   strr   r   r(   r?   rB   rC   rE   rL   r+   rO   propertyr   r   rS   r   rT   intrV   rW   r]   ra   rh   staticmethodrk   rj   ro   r   r   r   r    r5   )   sP      



r5   c                   @   s2   e Zd ZdZdd ZdddZdd Zd	d
 ZdS )CountryDescriptoraQ  
    A descriptor for country fields on a model instance. Returns a Country when
    accessed so you can do things like::

        >>> from people import Person
        >>> person = Person.object.get(name='Chris')

        >>> person.country.name
        'New Zealand'

        >>> person.country.flag
        '/static/flags/nz.gif'
    c                 C   s
   || _ d S r%   )field)r'   ru   r   r   r    r(      s    zCountryDescriptor.__init__Nc                    s^   |d kr S  j j|jkr,|j j jgd |j j j } j jrT fdd|D S  |S )N)fieldsc                    s   g | ]}  |qS r   r&   r   r6   r*   r   r    rd      s     z-CountryDescriptor.__get__.<locals>.<listcomp>)ru   r   __dict__Zrefresh_from_dbmultipler#   )r'   instanceownerr.   r   r*   r    __get__   s    zCountryDescriptor.__get__c                 C   s   t || jj| jj| jjdS )Nr7   )r5   ru   countries_flag_urlcountries_str_attrr   )r'   r6   r   r   r    r#      s    zCountryDescriptor.countryc                 C   s   | j |}||j| j j< d S r%   )ru   get_clean_valuerx   r   )r'   rz   r.   r   r   r    __set__   s    zCountryDescriptor.__set__)NN)r1   r2   r3   __doc__r(   r|   r#   r   r   r   r   r    rt      s
   
rt   c                       s   e Zd Z fddZ  ZS )LazyChoicesMixinc                    s   t  | || j_dS )z3
        Also update the widget's choices.
        N)super_set_choiceswidgetchoicesr'   r.   rI   r   r    r      s    zLazyChoicesMixin._set_choices)r1   r2   r3   r   __classcell__r   r   r   r    r      s   r   c                   @   s    e Zd ZU dZeed< ejZdS )LazyTypedChoiceFieldzL
    A form TypedChoiceField that respects choices being a lazy object.
    r   N)	r1   r2   r3   r   r   __annotations__r   Z
LazySelectr   r   r   r   r    r      s   
r   c                   @   s    e Zd ZU dZeed< ejZdS )LazyTypedMultipleChoiceFieldzT
    A form TypedMultipleChoiceField that respects choices being a lazy object.
    r   N)	r1   r2   r3   r   r   r   r   ZLazySelectMultipler   r   r   r   r    r      s   
r   c                       s   e Zd ZU dZeZeed< eed fddZ	 fddZ
dd	 Zd
d Z fddZ fddZ fddZdd Zdd Z fddZd& fdd	ZeeeZ fddZ fddZ fd d!Zd"d# Z fd$d%Z  ZS )'CountryFieldzb
    A country field for Django models that provides all ISO 3166-1 countries as
    choices.
    r   )rK   kwargsc                    s   | dd }|r| nt| _| dd | _| dd| _| dd | _| dd | _| dd| _| d	d| _| j|d
< d|kr| jrt| jd t	dd | jjD  |d< nt
dd | jjD |d< t j|| d S )Nr   r}   r~   r6   blank_labelry   multiple_uniqueTmultiple_sortr   
max_lengthre   c                 s   s   | ]}t |V  qd S r%   rN   rw   r   r   r    	<genexpr>  s     z(CountryField.__init__.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r%   r   rw   r   r   r    r     s    )popr   r}   r~   r   ry   r   r   rN   summaxr   r(   )r'   rK   r   Zcountries_classr   r   r    r(     s*    
zCountryField.__init__c                    s    t  jf |}||   |S r%   )r   checkextend_check_multiple)r'   r   errorsr   r   r    r   "  s    zCountryField.checkc                 C   s>   | j r| jsg S d}| js"|d7 }|d7 }tjd| d|dgS )Nz&Remove null=True argument on the fieldz8 (just add blank=True if you want to allow no selection).z5Field specifies multiple=True, so should not be null.zdjango_countries.E100)objidhint)ry   nullblankr   Error)r'   r   r   r   r    r   '  s    zCountryField._check_multiplec                 C   s   dS )Nr   r   r*   r   r   r    get_internal_type9  s    zCountryField.get_internal_typec                    s&   t  || t|| j| |  d S r%   )r   contribute_to_classsetattrr   descriptor_class)r'   clsr   r   r   r    r   <  s    z CountryField.contribute_to_classc                    s   t t| j||}| |S )z)Returns field's value just before saving.)r   r   pre_saveget_prep_value)r'   rK   r   r.   r   r   r    r   @  s    zCountryField.pre_savec                    s2   |  |}| jr"|rd|nd}tt| |S )z:Returns field's value prepared for saving into a database.,r=   )r   ry   rJ   r   r   r   r   r   r   r    r   E  s    
zCountryField.get_prep_valuec                 C   s$   t |dr|j}|d krd S t|S )Nr6   )hasattrr6   r   r   r   r   r    country_to_textL  s
    
zCountryField.country_to_textc                 C   s   |d krd S | j s| |S t|ttfrPt|trHd|krH|d}qx|g}n(zt| W n tk
rv   |g}Y nX g }t }|D ]8}| |}|sq| j	r||krq|
| || q| jrt|}|S Nr   )ry   r   
isinstancerp   r5   splititer	TypeErrorsetr   addrH   r   sorted)r'   r.   Zcleaned_valueseencr   r   r    r   S  s4    


zCountryField.get_clean_valuec                    sp   t t|  \}}}}|dd | jr2| j|d< | js@d|d< | jsNd|d< | jtk	rd| jj|d< ||||fS )z
        Remove choices from deconstructed field, as this is the country list
        and not user editable.

        Not including the ``blank_label`` property, as this isn't database
        related.
        r   Nry   Fr   r   r   )	r   r   deconstructr   ry   r   r   r   rI   )r'   r   pathrK   r   r   r   r    r   q  s    

zCountryField.deconstructTNc                    sF   |d kr$| j d krt}nd| j fg}| jr.d}t j|||d|S )Nr=   F)include_blankblank_choice)r   r   ry   r   get_choices)r'   r   r   rK   r   r   r   r    r     s    
  zCountryField.get_choicesc                    s8   | d| jrtnt d|kr*t j|d< t jf |S )NZchoices_form_classZcoerce)
setdefaultry   r   r   r   	to_python	formfield)r'   r   r   r   r    r     s    zCountryField.formfieldc                    sR   | j st |S |s|S t|tr.|d}g }|D ]}|t | q6|S r   )ry   r   r   r   rp   r   rH   )r'   r.   outputitemr   r   r    r     s    

zCountryField.to_pythonc                    s   | j st ||S | jsdS |r^dd | jD }|D ]&}||kr6tj| jd dd|idq6| js|| j	krtj| jd dddS )	zR
        Use custom validation for when using a multiple countries field.
        Nc                 S   s   g | ]\}}|qS r   r   )r   Z
option_keyZoption_valuer   r   r    rd     s     z)CountryField.validate.<locals>.<listcomp>Zinvalid_choicer.   )r6   paramsr   )r6   )
ry   r   validateeditabler   r   ZValidationErrorZerror_messagesr   Zempty_values)r'   r.   Zmodel_instancer   Zsingle_valuer   r   r    r     s    zCountryField.validatec                 C   s   |  |}| |S )z6
        Ensure data is serialized correctly.
        )Zvalue_from_objectr   )r'   r   r.   r   r   r    value_to_string  s    
zCountryField.value_to_stringc                    s$   | j s|dkrd| }t |S )N)
containsZ	icontains
startswithZistartswithendswithZ	iendswithregexZiregexr   ZinameZcountry_)ry   r   
get_lookup)r'   lookup_namer   r   r    r     s    
zCountryField.get_lookup)TN)r1   r2   r3   r   rt   r   r   r   r   r(   r   r   r   r   r   r   r   r   r   r   r   r^   r   r   r   r   r   r   r   r   r   r    r      s(   

	r   c                   @   s.   e Zd ZU dZdZeed< dd Zdd ZdS )	ExactNameLookupZcountry_nameFinsensitivec                 C   s"   t t| jjjjt| j| jdS )N)r   )	r	   r   lhsoutput_fieldr   by_namer   rhsr   r*   r   r   r    get_prep_lookup  s     zExactNameLookup.get_prep_lookupc                 C   s   |j d | S )Nexact)	operators)r'   
connectionr   r   r   r    
get_rhs_op  s    zExactNameLookup.get_rhs_opN)	r1   r2   r3   r   r   rM   r   r   r   r   r   r   r    r     s   
r   c                   @   s   e Zd ZU dZdZeed< dS )IExactNameLookupZcountry_inameTr   N)r1   r2   r3   r   r   rM   r   r   r   r   r    r     s   
r   c                       s>   e Zd ZU eed< dZeed< dZeed<  fddZ  Z	S )FullNameLookupexprFr   Tescape_regexc                    s   t | jtr| jj| jr$t| jn| jd}tt	| j
jjj|d| jd}t| jdkr| j| j ksp| jr|| j  |S t  S )N)rR   T)r   r      )r   r   rp   r   rX   r   rer   r	   r   r   r   r   r   r   rN   rf   r   r   r   )r'   r.   optionsr   r   r    r     s"      zFullNameLookup.get_prep_lookup)
r1   r2   r3   rp   r   r   rM   r   r   r   r   r   r   r    r     s   
r   c                   @   s   e Zd ZdZdZdS )CountryContainsZcountry_contains{text}Nr1   r2   r3   r   r   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdZdS )CountryIContainsZcountry_icontainsTNr1   r2   r3   r   r   r   r   r   r    r   	  s   r   c                   @   s   e Zd ZdZdZdS )CountryStartswithZcountry_startswithz^{text}Nr   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdZdS )CountryIStartswithZcountry_istartswithTNr   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdZdS )CountryEndswithZcountry_endswithz{text}$Nr   r   r   r   r    r     s   r   c                   @   s   e Zd ZdZdZdS )CountryIEndswithZcountry_iendswithTNr   r   r   r   r    r   !  s   r   c                   @   s   e Zd ZdZdZdZdS )CountryRegexZcountry_regexr   FN)r1   r2   r3   r   r   r   r   r   r   r    r   '  s   r   c                   @   s   e Zd ZdZdZdS )CountryIRegexZcountry_iregexTNr   r   r   r   r    r   .  s   r   c                 C   s
   t | tS r%   )r   r   )fr   r   r    <lambda>4      r   )Hr   typingr   r   r   r   r   r   r   r	   urllibr
   rZ   pkg_resourcesZdjangor   Zdjango.contrib.admin.filtersr   Zdjango.corer   r   Zdjango.db.modelsr   Zdjango.db.models.fieldsr   r   Zdjango.utils.encodingr   Zdjango.utils.functionalr   Zdjango.utils.htmlr   rQ   Zdjango_countriesr   r   r   r   r   Zdjango_countries.confr   iter_entry_pointsrl   r"   r5   rt   r   rp   Z_ChoiceZ_ChoiceNamedGroupZ_FieldChoicesZTypedChoiceFieldr   ZTypedMultipleChoiceFieldr   r   Zregister_lookupZExactr   r   ZInr   r   r   r   r   r   r   r   r   registerZCountryFilterr   r   r   r    <module>   sd   ( *			 \