a
    }c                     @   s   d dl Zd dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
mZ d dlmZmZmZ d dlmZ d dlmZ d	ZG d
d deZdS )    N)partial)	urlencode)AdapterHTTPError)GeocoderQueryErrorGeocoderQuotaExceeded)DEFAULT_SENTINELNONE_RESULTGeocoder)Location)logger)Geocodioc                       s   e Zd ZdZh dZdZdZdZdeededd fdd	
Z	dd
edddZ
d
eddddZdddZdd Zdd Z  ZS )r   zGeocoder using the Geocod.io API.

    Documentation at:
        https://www.geocod.io/docs/

    Pricing details:
        https://www.geocod.io/pricing/

    .. versionadded:: 2.2
    >   ZstreetZpostal_codeZcountrystateZcityzapi.geocod.ioz/v1.6/geocodez/v1.6/reverseNschemetimeoutproxies
user_agentssl_contextadapter_factoryc                   s"   t  j||||||d || _dS )a  
        :param str api_key:
            A valid Geocod.io API key. (https://dash.geocod.io/apikey/create)

        :param str scheme:
            See :attr:`geopy.geocoders.options.default_scheme`.

        :param int timeout:
            See :attr:`geopy.geocoders.options.default_timeout`.

        :param dict proxies:
            See :attr:`geopy.geocoders.options.default_proxies`.

        :param str user_agent:
            See :attr:`geopy.geocoders.options.default_user_agent`.

        :type ssl_context: :class:`ssl.SSLContext`
        :param ssl_context:
            See :attr:`geopy.geocoders.options.default_ssl_context`.

        :param callable adapter_factory:
            See :attr:`geopy.geocoders.options.default_adapter_factory`.
        r   N)super__init__api_key)selfr   r   r   r   r   r   r   	__class__ T/var/www/html/django/DPS/env/lib/python3.9/site-packages/geopy/geocoders/geocodio.pyr   '   s    "zGeocodio.__init__T)limitexactly_oner   c          	         s   t |tjjr& fdd| D }nd|i} j|d< |rD||d< |rPd|d< d j j jf }d	|t
|f}td	 jj| t j|d
} j|||dS )a  
        Return a location point by address.

        :param query: The address, query or a structured query
            you wish to geocode.

            For a structured query, provide a dictionary whose keys
            are one of: `street`, `city`, `state`, `postal_code` or `country`.
        :type query: dict or str

        :param int limit: The maximum number of matches to return. This will be reset
            to 1 if ``exactly_one`` is ``True``.

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        c                    s    i | ]\}}| j v r||qS r   )structured_query_params).0keyvalr   r   r   
<dictcomp>u   s   
z$Geocodio.geocode.<locals>.<dictcomp>qr   r      	%s://%s%s?z%s.geocode: %sr   r   )
isinstancecollectionsabcMappingitemsr   r   domaingeocode_pathjoinr   r   debugr   __name__r   _parse_json_call_geocoder)	r   queryr   r   r   paramsapiurlcallbackr   r#   r   geocodeS   s    !

zGeocodio.geocode)r   r   r   c          	      C   s   |  || jd}|rd}|dur*||d< d| j| j| jf }d|t|f}td| j	j
| t| j|d}| j|||d	S )
a5  Return an address by location point.

        :param str query: The coordinates for which you wish to obtain the
            closest human-readable addresses

        :param bool exactly_one: Return one result or a list of results, if
            available.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :param int limit: The maximum number of matches to return. This will be reset
            to 1 if ``exactly_one`` is ``True``.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        )r%   r   r&   Nr   r'   r(   z%s.reverse: %sr)   r*   )Z_coerce_point_to_stringr   r   r0   reverse_pathr2   r   r   r3   r   r4   r   r5   r6   )	r   r7   r   r   r   r8   r9   r:   r;   r   r   r   reverse   s    zGeocodio.reversec                    sB   | dg }|sdS dd  |r, |d S  fdd|D S dS )z7Returns location, (latitude, longitude) from json feed.resultsNc                 S   s2   |  d}| d d }| d d }t|||f| S )z4Get the location, lat, lng from a single json place.Zformatted_addresslocationZlatZlng)getr
   )placer@   ZlatitudeZ	longituder   r   r   parse_place   s    
z)Geocodio._parse_json.<locals>.parse_placer   c                    s   g | ]} |qS r   r   )r    rB   rC   r   r   
<listcomp>       z(Geocodio._parse_json.<locals>.<listcomp>)rA   )r   pager   Zplacesr   rD   r   r5      s    zGeocodio._parse_jsonc                 C   s   t |tsdS |jdu s"|jdu r&dS |jdkr`| |}d| v rVd| v rVtS t|||jdkr| |}d}||v rt||dS )a  Custom exception handling for invalid queries and exceeded quotas.

        Geocod.io returns a ``422`` status code for invalid queries, which is not mapped
        in :const:`~geopy.geocoders.base.ERROR_CODE_MAP`. The service also returns a
        ``403`` status code for exceeded quotas instead of the ``429`` code mapped in
        :const:`~geopy.geocoders.base.ERROR_CODE_MAP`
        Ni  zcould not geocode addresszpostal code or city requiredi  z>You can't make this request as it is above your daily maximum.)	r+   r   status_codetext_get_error_messagelowerr   r   r   )r   errorerror_messageZquota_exceeded_snippetr   r   r   _geocoder_exception_handler   s"    







z$Geocodio._geocoder_exception_handlerc                 C   s8   zt |jd}W n ty,   d}Y n0 |p6|jS )zVTry to extract an error message from the 'error' property of a JSON response.
        rL   N)jsonloadsrI   rA   
ValueError)r   rL   rM   r   r   r   rJ      s
    
zGeocodio._get_error_message)T)r4   
__module____qualname____doc__r   r0   r1   r=   r   r   r<   r>   r5   rN   rJ   __classcell__r   r   r   r   r      s.   0=+
r   )collections.abcr,   rO   	functoolsr   urllib.parser   Zgeopy.adaptersr   Z	geopy.excr   r   Zgeopy.geocoders.baser   r   r	   Zgeopy.locationr
   Z
geopy.utilr   __all__r   r   r   r   r   <module>   s   