o
    ÔèFh‡  ã                   @   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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   z¹Geocoder using the Geocod.io API.

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

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

    .. versionadded:: 2.2
    >   ÚcityÚstateÚstreetÚcountryÚpostal_codezapi.geocod.ioz/v1.6/geocodez/v1.6/reverseN)ÚschemeÚtimeoutÚproxiesÚ
user_agentÚssl_contextÚadapter_factoryÚdomainc          	         s0   t ƒ j||||||d� || _|r|| _dS dS )aG  
        :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`.

        :param str domain: base api domain

            .. versionadded:: 2.4
        )r   r   r   r   r   r   N)ÚsuperÚ__init__Úapi_keyr   )	Úselfr   r   r   r   r   r   r   r   ©Ú	__class__© úQ/var/www/html/loop/nvenv/lib/python3.10/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< |r"||d< |r(d|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>|   s
    
ýz$Geocodio.geocode.<locals>.<dictcomp>Úqr   r!   é   ú	%s://%s%sú?z%s.geocode: %s©r"   ©r   )Ú
isinstanceÚcollectionsÚabcÚMappingÚitemsr   r   r   Úgeocode_pathÚjoinr   r   Údebugr   Ú__name__r   Ú_parse_jsonÚ_call_geocoder)	r   Úqueryr!   r"   r   ÚparamsÚapiÚurlÚcallbackr   r'   r    ÚgeocodeZ   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.   )Ú_coerce_point_to_stringr   r   r   Úreverse_pathr5   r   r   r6   r   r7   r   r8   r9   )	r   r:   r"   r   r!   r;   r<   r=   r>   r   r   r    Úreverse“   s   þzGeocodio.reversec                    s>   |  dg ¡}|s
dS dd„ ‰ |rˆ |d ƒS ‡ fdd„|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.Úformatted_addressÚlocationÚlatÚlng)Úgetr
   )ÚplacerE   ÚlatitudeÚ	longituder   r   r    Úparse_placeÅ   s   
z)Geocodio._parse_json.<locals>.parse_placer   c                    s   g | ]}ˆ |ƒ‘qS r   r   )r$   rI   ©rL   r   r    Ú
<listcomp>Ï   s    z(Geocodio._parse_json.<locals>.<listcomp>)rH   )r   Úpager"   Úplacesr   rM   r    r8   ¾   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r0|  |¡}d| ¡ v r+d| ¡ v r+tS t|ƒ|‚|jdkrE|  |¡}d}||v rGt|ƒ|‚dS 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_messageÚ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w |p|jS )zVTry to extract an error message from the 'error' property of a JSON response.
        rU   N)ÚjsonÚloadsrR   rH   Ú
ValueError)r   rU   rV   r   r   r    rS   ì   s   ÿ
zGeocodio._get_error_message)T)r7   Ú
__module__Ú__qualname__Ú__doc__r#   r   r4   rA   r   r   r?   rB   r8   rX   rS   Ú__classcell__r   r   r   r    r      s2    ö7ú=ú
+r   )Úcollections.abcr0   rY   Ú	functoolsr   Úurllib.parser   Úgeopy.adaptersr   Ú	geopy.excr   r   Úgeopy.geocoders.baser   r   r	   Úgeopy.locationr
   Ú
geopy.utilr   Ú__all__r   r   r   r   r    Ú<module>   s    