a
     ÑOcé*  ã                   @   sà   d Z zddlZW n ey&   dZY n0 ddlZddlZddlmZmZ ddlmZ ddl	m
Z
mZmZmZmZmZ ddlmZmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ G dd„ dƒZG dd„ dƒZdS )zo
maxminddb.reader
~~~~~~~~~~~~~~~~

This module contains the pure Python database reader and related classes.

é    N)ÚIPv4AddressÚIPv6Address)ÚPathLike)ÚAnyÚAnyStrÚIOÚOptionalÚTupleÚUnion)Ú	MODE_AUTOÚ	MODE_MMAPÚ	MODE_FILEÚMODE_MEMORYÚMODE_FD)ÚDecoder)ÚInvalidDatabaseError)Ú
FileBuffer)ÚRecordc                   @   s$  e Zd ZU dZdZdZeeedf e	d< dZ
ee e	d< efeeeeef eddœd	d
„Zddœdd„Zeeeef ee dœdd„Zeeeef eee ef dœdd„Zeeeef dœdd„Zeedœdd„Zeeedœdd„Zeedœdd„Zddœd d!„Zddœd"d#„Z d dœd$d%„Z!dS )&ÚReaderz‰
    Instances of this class provide a reader for the MaxMind DB format. IP
    addresses can be looked up using the ``get`` method.
    é   s   «ÍïMaxMind.comz	mmap.mmapÚ_bufferNÚ_ipv4_start)ÚdatabaseÚmodeÚreturnc           	      C   sÊ  |t krts|tkrht|dƒ�4}tj| ¡ dtjd�| _| j ¡ | _W d  ƒ n1 sX0    Y  |}n®|t t	fv r�t
|ƒ| _| j ¡ | _|}n†|tkrÞt|dƒ�&}| ¡ | _t| jƒ| _W d  ƒ n1 sÎ0    Y  |}n8|tk�r| ¡ | _t| jƒ| _|j}ntd|› d�ƒ‚| j | jtd| jd ƒ¡}|dk�rT|  ¡  td	|› d
�ƒ‚|t| jƒ7 }t| j|ƒ}| |¡\}}t|tƒ�s˜td|› d�ƒ‚tf i |¤Ž| _t| j| jj| j ƒ| _d| _dS )a�  Reader for the MaxMind DB file format

        Arguments:
        database -- A path to a valid MaxMind DB file such as a GeoIP2 database
                    file, or a file descriptor in the case of MODE_FD.
        mode -- mode to open the database with. Valid mode are:
            * MODE_MMAP - read from memory map.
            * MODE_FILE - read database as standard file.
            * MODE_MEMORY - load database into memory.
            * MODE_AUTO - tries MODE_MMAP and then MODE_FILE. Default.
            * MODE_FD - the param passed via database is a file descriptor, not
                        a path. This mode implies MODE_MEMORY.
        Úrbr   )ÚaccessNzUnsupported open mode (z]). Only MODE_AUTO, MODE_FILE, MODE_MEMORY and MODE_FD are supported by the pure Python Readeri   éÿÿÿÿzError opening database file (z#). Is this a valid MaxMind DB file?z)Error reading metadata in database file (z).F) r   Úmmapr   ÚopenÚfilenoZACCESS_READr   ÚsizeÚ_buffer_sizer   r   r   ÚreadÚlenr   ÚnameÚ
ValueErrorÚrfindÚ_METADATA_START_MARKERÚmaxÚcloser   r   ÚdecodeÚ
isinstanceÚdictÚMetadataÚ	_metadataÚsearch_tree_sizeÚ_DATA_SECTION_SEPARATOR_SIZEÚ_decoderÚclosed)	Úselfr   r   Zdb_fileÚfilenameZmetadata_startZmetadata_decoderÚmetadataÚ_© r8   úG/var/www/html/gsl.tools/lib/python3.9/site-packages/maxminddb/reader.pyÚ__init__'   sT    *

*


ÿÿ

ÿ
ÿþzReader.__init__r.   ©r   c                 C   s   | j S )z7Return the metadata associated with the MaxMind DB file)r/   ©r4   r8   r8   r9   r6   m   s    zReader.metadata)Ú
ip_addressr   c                 C   s   |   |¡\}}|S )z˜Return the record for the ip_address in the MaxMind DB


        Arguments:
        ip_address -- an IP address in the standard string notation
        )Úget_with_prefix_len)r4   r=   Úrecordr7   r8   r8   r9   Úgetq   s    z
Reader.getc              
   C   s¦   t |tƒrt |¡}n|}zt|jƒ}W n. tyV } ztdƒ|‚W Y d}~n
d}~0 0 |jdkr~| j	j
dkr~td|› d�ƒ‚|  |¡\}}|rž|  |¡|fS d|fS )z¡Return a tuple with the record and the associated prefix length


        Arguments:
        ip_address -- an IP address in the standard string notation
        z/argument 1 must be a string or ipaddress objectNé   é   zError looking up zD. You attempted to look up an IPv6 address in an IPv4-only database.)r,   ÚstrÚ	ipaddressr=   Ú	bytearrayÚpackedÚAttributeErrorÚ	TypeErrorÚversionr/   Ú
ip_versionr&   Ú_find_address_in_treeÚ_resolve_data_pointer)r4   r=   ÚaddressZpacked_addressÚexÚpointerÚ
prefix_lenr8   r8   r9   r>   {   s    	
 
ÿzReader.get_with_prefix_len)rF   r   c                 C   s�   t |ƒd }|  |¡}| jj}d}||k rd||k rdd||d?  d|d  ? @ }|  ||¡}|d }q"||krtd|fS ||kr„||fS tdƒ‚d S )Né   r   é   é   é   zInvalid node in search tree)r$   Ú_start_noder/   Ú
node_countÚ
_read_noder   )r4   rF   Z	bit_countÚnoderV   ÚiÚbitr8   r8   r9   rK   š   s    

zReader._find_address_in_tree)Úlengthr   c                 C   s\   | j jdks|dkrdS | jr$| jS d}tdƒD ] }|| j jkrD qR|  |d¡}q0|| _|S )NrA   é€   r   é`   )r/   rJ   r   ÚrangerV   rW   )r4   r[   rX   r7   r8   r8   r9   rU   ­   s    zReader._start_node)Únode_numberÚindexr   c                 C   sä   || j j }| j j}|dkr@||d  }d| j||d …  }n”|dkrž|d|  }t| j||d … ƒ}|r€d|d @ |d< qÔd| ¡ @ d? }| d|¡ n6|d	krÆ||d  }| j||d … }ntd
|› �ƒ‚t 	d|¡d S )Né   rS   ó    é   rB   é   r   éð   é    zUnknown record size: s   !I)
r/   Únode_byte_sizeÚrecord_sizer   rE   ÚpopÚinsertr   ÚstructÚunpack)r4   r_   r`   Zbase_offsetrh   ÚoffsetZ
node_bytesZmiddler8   r8   r9   rW   ¾   s"    zReader._read_node)rO   r   c                 C   s:   || j j | j j }|| jkr&tdƒ‚| j |¡\}}|S )Nz,The MaxMind DB file's search tree is corrupt)r/   rV   r0   r"   r   r2   r+   )r4   rO   ZresolvedÚdatar7   r8   r8   r9   rL   Ô   s
    
zReader._resolve_data_pointerc                 C   s,   z| j  ¡  W n ty    Y n0 d| _dS )zBCloses the MaxMind DB file and returns the resources to the systemTN)r   r*   rG   r3   r<   r8   r8   r9   r*   Ý   s
    zReader.closec                 G   s   |   ¡  d S )N)r*   ©r4   Úargsr8   r8   r9   Ú__exit__å   s    zReader.__exit__c                 C   s   | j rtdƒ‚| S )Nz%Attempt to reopen a closed MaxMind DB)r3   r&   r<   r8   r8   r9   Ú	__enter__è   s    zReader.__enter__)"Ú__name__Ú
__module__Ú__qualname__Ú__doc__r1   r(   r
   Úbytesr   Ú__annotations__r   r   Úintr   r   r   r   r:   r6   rC   r   r   r   r@   r	   r>   rE   rK   rU   rW   rL   r*   rq   rr   r8   r8   r8   r9   r      s,   
ÿþFþ	r   c                   @   sJ   e Zd ZdZddœdd„Zeedœdd„ƒZeedœdd	„ƒZd
d„ Z	dS )r.   aâ  Metadata for the MaxMind DB reader


    .. attribute:: binary_format_major_version

      The major version number of the binary format used when creating the
      database.

      :type: int

    .. attribute:: binary_format_minor_version

      The minor version number of the binary format used when creating the
      database.

      :type: int

    .. attribute:: build_epoch

      The Unix epoch for the build time of the database.

      :type: int

    .. attribute:: database_type

      A string identifying the database type, e.g., "GeoIP2-City".

      :type: str

    .. attribute:: description

      A map from locales to text descriptions of the database.

      :type: dict(str, str)

    .. attribute:: ip_version

      The IP version of the data in a database. A value of "4" means the
      database only supports IPv4. A database with a value of "6" may support
      both IPv4 and IPv6 lookups.

      :type: int

    .. attribute:: languages

      A list of locale codes supported by the databse.

      :type: list(str)

    .. attribute:: node_count

      The number of nodes in the database.

      :type: int

    .. attribute:: record_size

      The bit size of a record in the search tree.

      :type: int

    Nr;   c                 K   s^   |d | _ |d | _|d | _|d | _|d | _|d | _|d | _|d | _|d	 | _d
S )zACreates new Metadata object. kwargs are key/value pairs from specrV   rh   rJ   Údatabase_typeÚ	languagesÚbinary_format_major_versionÚbinary_format_minor_versionÚbuild_epochÚdescriptionN)	rV   rh   rJ   rz   r{   r|   r}   r~   r   )r4   Úkwargsr8   r8   r9   r:   /  s    







zMetadata.__init__c                 C   s
   | j d S )z8The size of a node in bytes

        :type: int
        rB   )rh   r<   r8   r8   r9   rg   =  s    zMetadata.node_byte_sizec                 C   s   | j | j S )z8The size of the search tree

        :type: int
        )rV   rg   r<   r8   r8   r9   r0   E  s    zMetadata.search_tree_sizec                 C   s6   d  dd„ | j ¡ D ƒ¡}| j› d| jj› d|› d�S )Nz, c                 s   s    | ]\}}|› d |›�V  qdS )ú=Nr8   )Ú.0ÚkÚvr8   r8   r9   Ú	<genexpr>N  ó    z$Metadata.__repr__.<locals>.<genexpr>Ú.ú(ú))ÚjoinÚ__dict__Úitemsrt   Ú	__class__rs   ro   r8   r8   r9   Ú__repr__M  s    zMetadata.__repr__)
rs   rt   ru   rv   r:   Úpropertyry   rg   r0   rŽ   r8   r8   r8   r9   r.   î   s   @r.   ) rv   r   ÚImportErrorrD   rk   r   r   Úosr   Útypingr   r   r   r   r	   r
   Zmaxminddb.constr   r   r   r   r   Zmaxminddb.decoderr   Zmaxminddb.errorsr   Zmaxminddb.filer   Zmaxminddb.typesr   r   r.   r8   r8   r8   r9   Ú<module>   s"   
  T