§
    ÞËbý)  ã            	       ó&  — d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ dZdZg d¢Zej                             ej                             e¦  «        ¦  «        Z ed	d
¦  «        Z edd¦  «        Z G d„ de¦  «        Zej                             ed¦  «        fde	ej        ef         de
ee         ee         ee         f         fd„Zdedefd„Z e¦   «         \  ZZZde
e e f         fd„Z!d*dee         fd„Z"d*de#de#dee         fd„Z$d*de#de#de%defd„Z&de	ej        ef         de
e#e#f         fd„Z'd„ Z(d„ Z)de	ej        ef         defd„Z*d+de	ej        ef         de%defd!„Z+d,d"e	ee#f         de%de	ej        ef         defd#„Z,d,de%de	ej        ef         defd$„Z-de	ej        ef         dee         fd%„Z.d*de	ej        ef         dee         fd&„Z/d*de	ej        ef         dee         fd'„Z0d(„ Z1e2d)k    r e1¦   «          dS dS )-u˜  
puremagic is a pure python module that will identify a file based off it's
magic numbers. It is designed to be minimalistic and inherently cross platform
compatible, with no imports when used as a module.

Â© 2013-2022 Chris Griffith - License: MIT (see LICENSE)

Acknowledgements
Gary C. Kessler
    For use of his File Signature Tables, available at:
    http://www.garykessler.net/library/file_sigs.html
é    N)Úchain)Ú
namedtuple)ÚUnionÚTupleÚListzChris Griffithz1.14)
Ú
magic_fileÚmagic_stringÚmagic_streamÚ	from_fileÚfrom_stringÚfrom_streamÚext_from_filenameÚ	PureErrorÚmagic_footer_arrayÚmagic_header_arrayÚ	PureMagic©Ú
byte_matchÚoffsetÚ	extensionÚ	mime_typeÚnameÚPureMagicWithConfidence)r   r   r   r   r   Ú
confidencec                   ó   — e Zd ZdZdS )r   z.Do not have that type of file in our databanksN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú0/usr/lib/python3/dist-packages/puremagic/main.pyr   r   >   s   € € € € € Ø8Ð8Ð8Ð8r!   r   zmagic_data.jsonÚfilenameÚreturnc                 ó.  — t          | ¦  «        5 }t          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   t          d„ |d         D ¦   «         d„ ¬¦  «        }t          d„ |d         D ¦   «         d„ ¬¦  «        }d	„ |d
         D ¦   «         }|||fS )zRead the magic fileNc              3   ó4   K  — | ]}t          |¦  «        V — Œd S ©N©Ú_create_puremagic©Ú.0Úxs     r"   ú	<genexpr>z_magic_data.<locals>.<genexpr>H   ó+   è è € ÐDÐD¨qÕ'¨Ñ*Ô*ÐDÐDÐDÐDÐDÐDr!   Úheadersc                 ó   — | j         S r'   ©r   ©r,   s    r"   ú<lambda>z_magic_data.<locals>.<lambda>H   ó
   € ÐTUÔT`€ r!   )Úkeyc              3   ó4   K  — | ]}t          |¦  «        V — Œd S r'   r(   r*   s     r"   r-   z_magic_data.<locals>.<genexpr>I   r.   r!   Úfootersc                 ó   — | j         S r'   r1   r2   s    r"   r3   z_magic_data.<locals>.<lambda>I   r4   r!   c                 ó,   — g | ]}t          |¦  «        ‘ŒS r    r(   r*   s     r"   ú
<listcomp>z_magic_data.<locals>.<listcomp>J   s!   € ÐGÐGÐG¨1Õ# AÑ&Ô&ÐGÐGÐGr!   Úextension_only)ÚopenÚjsonÚloadÚsorted)r#   ÚfÚdatar/   r7   Ú
extensionss         r"   Ú_magic_datarC   B   sç   € õ 
ˆh‰Œð ˜1ÝŒy˜‰|Œ|ˆðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð åÐDÐD°D¸´OÐDÑDÔDÐJ`ÐJ`ÐaÑaÔa€GÝÐDÐD°D¸´OÐDÑDÔDÐJ`ÐJ`ÐaÑaÔa€GØGÐG°Ð5EÔ0FÐGÑGÔG€JØ�G˜ZÐ'Ð's   �1±5¸5r,   c                 ó°   — t          t          j        | d                              d¦  «        ¦  «        | d         | d         | d         | d         ¬¦  «        S )Nr   Úasciié   é   é   é   r   )r   ÚbinasciiÚ	unhexlifyÚencoder2   s    r"   r)   r)   N   sX   € ÝÝÔ% a¨¤d§k¢k°'Ñ&:Ô&:Ñ;Ô;ÀAÀaÄDÐTUÐVWÔTXÐdeÐfgÔdhÐopÐqrÔosðñ ô ð r!   c                  ó‚   — t          d„ t          D ¦   «         ¦  «        } t          d„ t          D ¦   «         ¦  «        }| |fS )z3The length of the largest magic string + its offsetc                 óF   — g | ]}t          |j        ¦  «        |j        z   ‘ŒS r    )Úlenr   r   r*   s     r"   r:   z _max_lengths.<locals>.<listcomp>Y   s)   € ÐVÐVÐV¸a�S ¤Ñ.Ô.°´Ñ9ÐVÐVÐVr!   c                 ó`   — g | ]+}t          |j        ¦  «        t          |j        ¦  «        z   ‘Œ,S r    )rO   r   Úabsr   r*   s     r"   r:   z _max_lengths.<locals>.<listcomp>Z   s/   € Ð[Ð[Ð[À1�S ¤Ñ.Ô.µ°Q´X±´Ñ>Ð[Ð[Ð[r!   )Úmaxr   r   )Úmax_header_lengthÚmax_footer_lengths     r"   Ú_max_lengthsrU   W   sJ   € åÐVÐVÕCUÐVÑVÔVÑWÔWÐÝÐ[Ð[ÕHZÐ[Ñ[Ô[Ñ\Ô\ÐØÐ/Ð/Ð/r!   c           	      ó  — g }| D ]˜}t          |j        ¦  «        dk    rdn3t          d                     t          |j        ¦  «        ¦  «        ¦  «        }|dk    r|r||j        k    rd}|                     t          dd|i|                     ¦   «         ¤Ž¦  «         Œ™|sJ|rHt          D ]@}||j        k    r3|                     t          dddi|                     ¦   «         ¤Ž¦  «         ŒA|st          d¦  «        ‚t          |d„ d	¬
¦  «        S )z:Rough confidence based on string length and file extensioné	   gš™™™™™é?z0.{0}gš™™™™™¹?gÍÌÌÌÌÌì?r   zCould not identify filec                 ó   — | j         S r'   ©r   r2   s    r"   r3   z_confidence.<locals>.<lambda>o   s   € ¨¬€ r!   T©r5   Úreverser    )rO   r   ÚfloatÚformatr   Úappendr   Ú_asdictÚextension_only_arrayr   r?   )ÚmatchesÚextÚresultsÚmatchÚconÚ	magic_rows         r"   Ú_confidencerg   ^   s7  € à€GØð Sð SˆÝ˜Ô)Ñ*Ô*¨aÒ/Ð/ˆcˆcµU¸7¿>º>Í#ÈeÔN^ÑJ_ÔJ_Ñ;`Ô;`Ñ5aÔ5aˆØ�#Š:ˆ:˜#ˆ: #¨¬Ò"8Ð"8ØˆCØ�ŠÕ.ÐQÐQ¸#ÐQÀÇÂÁÄÐQÐQÑRÔRÐRÐRàð _�sð _Ý-ð 	_ð 	_ˆIØ�iÔ)Ò)Ð)Ø—’Õ6Ð]Ð]À#Ð]È×IZÒIZÑI\ÔI\Ð]Ð]Ñ^Ô^Ð^øàð 3ÝÐ1Ñ2Ô2Ð2å�'Ð5Ð5¸tÐDÑDÔDÐDr!   ÚheaderÚfooterc                 ó‚  — t          ¦   «         }t          D ]a}|j        }|j        t          |j        ¦  «        z   }|t          | ¦  «        k    rŒ9| ||…         |j        k    r|                     |¦  «         Œbt          D ]1}|j        }||d…         |j        k    r|                     |¦  «         Œ2t          ||¦  «        S )z/Attempt to identify 'data' by its magic numbersN)Úlistr   r   rO   r   r^   r   rg   )rh   ri   rb   ra   rf   ÚstartÚends          r"   Ú_identify_allrn   r   sÊ   € õ
 ‰fŒf€GÝ'ð &ð &ˆ	ØÔ ˆØÔ¥ YÔ%9Ñ!:Ô!:Ñ:ˆØ•�V‘”ÒÐØØ�%˜�)Ô 	Ô 4Ò4Ð4Ø�NŠN˜9Ñ%Ô%Ð%øå'ð &ð &ˆ	ØÔ ˆØ�%�&�&Œ>˜YÔ1Ò1Ð1Ø�NŠN˜9Ñ%Ô%Ð%øå�w Ñ$Ô$Ð$r!   Úmimec                 óÀ   — | st          d¦  «        ‚t          | ||¦  «        d         }|r|j        S t          |j        t
          ¦  «        s|j        n|d         j        S )z=Discover what type of file it is based on the incoming stringúInput was emptyr   )Ú
ValueErrorrn   r   Ú
isinstancer   rk   )rh   ri   ro   rb   Úinfos        r"   Ú_magicru   ˆ   sc   € àð ,ÝÐ*Ñ+Ô+Ð+Ý˜ ¨Ñ-Ô-¨aÔ0€DØð ØŒ~ÐÝ!+¨D¬N½DÑ!AÔ!AÐXˆ4Œ>ˆ>ÀtÈAÄwÔGXÐXr!   c                 ó^  — t          ¦   «         \  }}t          | d¦  «        5 }|                     |¦  «        }	 |                     | t          j        ¦  «         n%# t          $ r |                     d¦  «         Y nw xY w|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   ||fS )z"Grab the start and end of the fileÚrbr   N)rU   r<   ÚreadÚseekÚosÚSEEK_ENDÚIOError)r#   Úmax_headÚmax_footÚfinÚheadÚfoots         r"   Ú_file_detailsr‚   ’   sê   € å%™œÑ€HˆhÝ	ˆh˜Ñ	Ô	ð  Ø�xŠx˜Ñ!Ô!ˆð	Ø�HŠH�h�Y¥¤Ñ,Ô,Ð,Ð,øÝð 	ð 	ð 	Ø�HŠH�Q‰KŒKˆKˆKˆKð	øøøà�xŠx‰zŒzˆðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð �ˆ:Ðs4   ¢B ¹!AÁB ÁA=Á:B Á<A=Á=B Â B$Â'B$c                 óN   — t          ¦   «         \  }}| d|…         | | d…         fS )z$Grab the start and end of the stringN)rU   )Ústringr}   r~   s      r"   Ú_string_detailsr…   Ÿ   s/   € å%™œÑ€HˆhØ�)�8�)Ô˜f h Y Z ZÔ0Ð0Ð0r!   c                 óÀ   — t          ¦   «         \  }}|                      |¦  «        }|                      | t          j        ¦  «         |                      ¦   «         }||fS )z$Grab the start and end of the stream)rU   rx   ry   rz   r{   )Ústreamr}   r~   r€   r�   s        r"   Ú_stream_detailsrˆ   ¥   sP   € å%™œÑ€HˆhØ�;Š;�xÑ Ô €DØ
‡K‚K��	�2œ;Ñ'Ô'Ð'Ø�;Š;‰=Œ=€DØ�ˆ:Ðr!   c                 ón  — 	 t          | ¦  «                             ¦   «                              dd¦  «        \  }}n# t          $ r Y dS w xY wd                     |¦  «        }d„ t          t          t          ¦  «        D ¦   «         }|dd…                              d¦  «        r|dd…         |z   }||v r|S |S )zŸScan a filename for its extension.

    :param filename: string of the filename
    :return: the extension off the end (empty string if it can't find one)
    ú.rF   Ú z.{0}c                 ó   — g | ]	}|j         ‘Œ
S r    )r   r*   s     r"   r:   z%ext_from_filename.<locals>.<listcomp>¹   s   € ÐSÐSÐS �”ÐSÐSÐSr!   éüÿÿÿN)	ÚstrÚlowerÚrsplitrr   r]   r   r   r   Ú
startswith)r#   Úbaserb   Úall_extsÚlong_exts        r"   r   r   ®   sÊ   € ðÝ˜‘M”M×'Ò'Ñ)Ô)×0Ò0°°aÑ8Ô8‰	ˆˆcˆcøÝð ð ð Øˆrˆrðøøøà
�-Š-˜Ñ
Ô
€CØSÐS¥UÕ+=Õ?QÑ%RÔ%RÐSÑSÔS€HàˆBˆCˆC„y×Ò˜CÑ Ô ð à˜˜˜”9˜s‘?ˆØ�xÐÐØˆOØ€Js   ‚8; »
A	ÁA	Fc                 ód   — t          | ¦  «        \  }}t          |||t          | ¦  «        ¦  «        S )a  Opens file, attempts to identify content based
    off magic number and will return the file extension.
    If mime is True it will return the mime type instead.

    :param filename: path to file
    :param mime: Return mime, not extension
    :return: guessed extension or mime
    )r‚   ru   r   )r#   ro   r€   r�   s       r"   r   r   Ã   s2   € õ ˜xÑ(Ô(�J€Dˆ$Ý�$˜˜dÕ$5°hÑ$?Ô$?Ñ@Ô@Ð@r!   r„   c                 óÄ   — t          | t          ¦  «        r|                      d¦  «        } t          | ¦  «        \  }}|rt	          |¦  «        nd}t          ||||¦  «        S )a˜  Reads in string, attempts to identify content based
    off magic number and will return the file extension.
    If mime is True it will return the mime type instead.
    If filename is provided it will be used in the computation.

    :param string: string representation to check
    :param mime: Return mime, not extension
    :param filename: original filename
    :return: guessed extension or mime
    zutf-8N)rs   rŽ   rL   r…   r   ru   )r„   ro   r#   r€   r�   rb   s         r"   r   r   Ñ   sd   € õ �&�#ÑÔð (Ø—’˜wÑ'Ô'ˆÝ  Ñ(Ô(�J€Dˆ$Ø)1Ð
;Õ
˜HÑ
%Ô
%Ð
%°t€CÝ�$˜˜d CÑ(Ô(Ð(r!   c                 óp   — t          | ¦  «        \  }}|rt          |¦  «        nd}t          ||||¦  «        S )a˜  Reads in stream, attempts to identify content based
    off magic number and will return the file extension.
    If mime is True it will return the mime type instead.
    If filename is provided it will be used in the computation.

    :param stream: stream representation to check
    :param mime: Return mime, not extension
    :param filename: original filename
    :return: guessed extension or mime
    N)rˆ   r   ru   )r‡   ro   r#   r€   r�   rb   s         r"   r   r   ã   sA   € õ ! Ñ(Ô(�J€Dˆ$Ø)1Ð
;Õ
˜HÑ
%Ô
%Ð
%°t€CÝ�$˜˜d CÑ(Ô(Ð(r!   c                 óà   — t          | ¦  «        \  }}|st          d¦  «        ‚	 t          ||t          | ¦  «        ¦  «        }n# t          $ r g }Y nw xY w|                     d„ d¬¦  «         |S )zÌ
    Returns list of (num_of_matches, array_of_matches)
    arranged highest confidence match first.

    :param filename: path to file
    :return: list of possible matches, highest confidence first
    rq   c                 ó   — | j         S r'   rY   r2   s    r"   r3   zmagic_file.<locals>.<lambda>  ó   € ˜AœL€ r!   TrZ   )r‚   rr   rn   r   r   Úsort)r#   r€   r�   rt   s       r"   r   r   ó   s�   € õ ˜xÑ(Ô(�J€Dˆ$Øð ,ÝÐ*Ñ+Ô+Ð+ðÝ˜T 4Õ):¸8Ñ)DÔ)DÑEÔEˆˆøÝð ð ð Øˆˆˆðøøøà‡I‚IÐ(Ð(°$€IÑ7Ô7Ð7Ø€Ks   ¥A ÁAÁAc                 óÄ   — | st          d¦  «        ‚t          | ¦  «        \  }}|rt          |¦  «        nd}t          |||¦  «        }|                     d„ d¬¦  «         |S )aC  
    Returns tuple of (num_of_matches, array_of_matches)
    arranged highest confidence match first
    If filename is provided it will be used in the computation.

    :param string: string representation to check
    :param filename: original filename
    :return: list of possible matches, highest confidence first
    rq   Nc                 ó   — | j         S r'   rY   r2   s    r"   r3   zmagic_string.<locals>.<lambda>  rš   r!   TrZ   )rr   r…   r   rn   r›   )r„   r#   r€   r�   rb   rt   s         r"   r	   r	     st   € ð ð ,ÝÐ*Ñ+Ô+Ð+Ý  Ñ(Ô(�J€Dˆ$Ø)1Ð
;Õ
˜HÑ
%Ô
%Ð
%°t€CÝ˜˜t SÑ)Ô)€DØ‡I‚IÐ(Ð(°$€IÑ7Ô7Ð7Ø€Kr!   c                 óÄ   — t          | ¦  «        \  }}|st          d¦  «        ‚|rt          |¦  «        nd}t          |||¦  «        }|                     d„ d¬¦  «         |S )a>  Returns tuple of (num_of_matches, array_of_matches)
    arranged highest confidence match first
    If filename is provided it will be used in the computation.

    :param stream: stream representation to check
    :param filename: original filename
    :return: list of possible matches, highest confidence first
    rq   Nc                 ó   — | j         S r'   rY   r2   s    r"   r3   zmagic_stream.<locals>.<lambda>'  rš   r!   TrZ   )rˆ   rr   r   rn   r›   )r‡   r#   r€   r�   rb   rt   s         r"   r
   r
     st   € õ ! Ñ(Ô(�J€Dˆ$Øð ,ÝÐ*Ñ+Ô+Ð+Ø)1Ð
;Õ
˜HÑ
%Ô
%Ð
%°t€CÝ˜˜t SÑ)Ô)€DØ‡I‚IÐ(Ð(°$€IÑ7Ô7Ð7Ø€Kr!   c            
      óJ  — ddl m} dd l} |d¬¦  «        }|                     ddddd	¬
¦  «         |                     dd¬¦  «         |                     | r| n|j        dd …         ¦  «        } | j        D ]­}t          j         	                    |¦  «        s#t          d                     |¦  «        ¦  «         ŒD	 t          d                     |t          || j        ¦  «        ¦  «        ¦  «         Œ|# t          $ r% t          d                     |¦  «        ¦  «         Y Œªw xY wd S )Nr   )ÚArgumentParserzpuremagic is a pure python file identification module.It looks for matching magic numbers in the file to locate the file type. )Údescriptionz-mz--mimeÚ
store_truero   z)Return the mime type instead of file type)ÚactionÚdestÚhelpÚfilesú+)ÚnargsrF   zFile '{0}' does not exist!z'{0}' : {1}z'{0}' : could not be Identified)Úargparser¡   ÚsysÚadd_argumentÚ
parse_argsÚargvr§   rz   ÚpathÚexistsÚprintr]   r   ro   r   )Úargsr¡   r«   ÚparserÚfns        r"   Úcommand_line_entryrµ   +  so  € Ø'Ð'Ð'Ð'Ð'Ð'Ø€J€J€Jàˆ^ðXðñ ô €Fð ×ÒØˆh˜|°&Ð?jð ñ ô ð ð ×Ò˜ sÐÑ+Ô+Ð+Ø×Ò TÐ;˜T˜T¨s¬x¸¸¸¬|Ñ<Ô<€DàŒjð @ð @ˆÝŒw�~Š~˜bÑ!Ô!ð 	ÝÐ.×5Ò5°bÑ9Ô9Ñ:Ô:Ð:Øð	@Ý�-×&Ò& r­9°R¸¼Ñ+CÔ+CÑDÔDÑEÔEÐEÐEøÝð 	@ð 	@ð 	@ÝÐ3×:Ò:¸2Ñ>Ô>Ñ?Ô?Ð?Ð?Ð?ð	@øøøð@ð @s   Â:6C1Ã1,D ÄD Ú__main__r'   )F)FN)3r   rz   r=   rJ   Ú	itertoolsr   Úcollectionsr   Útypingr   r   r   Ú
__author__Ú__version__Ú__all__r¯   ÚabspathÚdirnameÚ__file__Úherer   r   ÚLookupErrorr   ÚjoinÚPathLikerŽ   rC   r)   r   r   r`   ÚintrU   rg   Úbytesrn   Úboolru   r‚   r…   rˆ   r   r   r   r   r   r	   r
   rµ   r   r    r!   r"   ú<module>rÇ      s˜  ððð ð 
€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø %Ð %Ð %Ð %Ð %Ð %Ð %Ð %Ð %Ð %à€
Ø€ðð ð €ð 
„w‡‚�r”w—’ xÑ0Ô0Ñ1Ô1€àˆJØðñ	ô 	€	ð %˜*Øðñ
ô 
Ð ð9ð 9ð 9ð 9ð 9�ñ 9ô 9ð 9ð
 )+¬¯ª°TÐ;LÑ(MÔ(Mð	(ð 	(Ø�B”K Ð$Ô%ð	(à
ˆ4�	Œ?˜D œO¨T°)¬_Ð<Ô=ð	(ð 	(ð 	(ð 	(ð˜ð  )ð ð ð ð ð @K¸{¹}¼}Ñ <Ð Ð&Ð(<ð0�e˜C ˜H”oð 0ð 0ð 0ð 0ðEð E dÐ+BÔ&Cð Eð Eð Eð Eð(%ð %˜%ð %¨ð %¸TÐBYÔ=Zð %ð %ð %ð %ð,Yð Y�5ð Y %ð Y¨tð YÀ#ð Yð Yð Yð Yð
˜E "¤+¨sÐ"2Ô3ð 
¸¸eÀU¸lÔ8Kð 
ð 
ð 
ð 
ð1ð 1ð 1ðð ð ð  b¤k°3Ð&6Ô 7ð ¸Cð ð ð ð ð*Að A˜˜bœk¨3Ð.Ô/ð A°tð AÈð Að Að Að Að)ð )˜˜c 5˜jÔ)ð )°ð )ÈÈrÌ{Ð\_ÐO_ÔI`ð )Ðloð )ð )ð )ð )ð$)ð )˜dð )°e¸B¼KÈÐ<LÔ6Mð )ÐY\ð )ð )ð )ð )ð ˜˜rœ{¨CÐ/Ô0ð °TÐ:QÔ5Rð ð ð ð ð&ð  5¨¬°cÐ)9Ô#:ð ÀdÐKbÔFcð ð ð ð ð&ð  5¨¬°cÐ)9Ô#:ð ÀdÐKbÔFcð ð ð ð ð$@ð @ð @ð4 ˆzÒÐØÐÑÔÐÐÐð Ðr!   