3
v_>                 @   sd  d Z ddlZddlZddlZddlZddlmZ ddlZddlm	Z	m
Z
 ddlmZ dZi Zdadadadaejd dkZdd	 Zd1d
dZG dd dZG dd dZG dd dZG dd dZeddZeddZeddZeddZeddZeddZ eddZ!eddZ"eddZ#d a$d!d" Z%d#d$ Z&d%d& Z'd2d(d)Z(d3d*d+Z)d4d-d.Z*d/d0 Z+dS )5a  
This module is based on a rox module (LGPL):

http://cvs.sourceforge.net/viewcvs.py/rox/ROX-Lib2/python/rox/mime.py?rev=1.21&view=log

This module provides access to the shared MIME database.

types is a dictionary of all known MIME types, indexed by the type name, e.g.
types['application/x-python']

Applications can install information about MIME types by storing an
XML file as <MIME>/packages/<application>.xml and running the
update-mime-database command, which is provided by the freedesktop.org
shared mime database package.

See http://www.freedesktop.org/standards/shared-mime-info-spec/ for
information about the format of these files.

(based on version 0.13)
    N)BaseDirectory)minidomXML_NAMESPACE)defaultdictz5http://www.freedesktop.org/standards/shared-mime-info   c             C   s   dj dd | jD j S )zGet text of XML node c             S   s   g | ]
}|j qS  )Z	nodeValue).0nr   r   */usr/lib/python3/dist-packages/xdg/Mime.py
<listcomp>.   s    z"_get_node_data.<locals>.<listcomp>)joinZ
childNodesstrip)Znoder   r   r   _get_node_data,   s    r   c             C   sJ   |dkr d| kr | j dd\} }| |ftkr>t| |t| |f< t| |f S )zGet the MIMEtype object for this type, creating a new one if needed.
    
    The name can either be passed as one part ('text/plain'), or as two
    ('text', 'plain').
    N/   )splittypesMIMEtype)mediasubtyper   r   r   lookup0   s
    r   c               @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )r   z#Type holding data about a MIME typec             C   sF   |rd|kst |rd|ks t ||ftks0t || _|| _d| _dS )z?Don't use this constructor directly; use mime.lookup() instead.r   N)AssertionErrorr   r   r   _comment)selfr   r   r   r   r   __init__>   s    zMIMEtype.__init__c             C   s   t jjd| j| jd }xtj|D ]x}tj|}|dkr<q$x^|j	j
tdD ]L}|jtdp^d}d|tjjk }|| jd kr|t|f| _|d	krLdS qLW q$W dS )
z>Loads comment for current language. Use get_comment() instead.mimez.xmlNcommentlangZenr   r      )ospathr   r   r   r   load_data_pathsr   parseZdocumentElementZgetElementsByTagNameNSFREE_NSZgetAttributeNSr   xdgZLocaleZlangsr   r   )r   resourcer!   docr   r   Zgoodnessr   r   r   _loadH   s    
 zMIMEtype._loadc             C   s*   | j dkr dt| f| _ | j  | j d S )z;Returns comment for current language, loading it if needed.Nr   r   )r   strr(   )r   r   r   r   get_commentW   s    
zMIMEtype.get_commentc             C   s&   t   t| }|tkr"tt| S | S )z:Returns the canonical MimeType object if this is an alias.)update_cacher)   aliasesr   )r   sr   r   r   	canonical_   s
    zMIMEtype.canonicalc             C   s    t   tdd tt|  D S )z5Returns a set of Mime types which this inherits from.c             s   s   | ]}t |V  qd S )N)r   )r	   tr   r   r   	<genexpr>j   s    z)MIMEtype.inherits_from.<locals>.<genexpr>)r+   setinheritancer)   )r   r   r   r   inherits_fromg   s    zMIMEtype.inherits_fromc             C   s   | j d | j S )Nr   )r   r   )r   r   r   r   __str__l   s    zMIMEtype.__str__c             C   s   d| | j pdf S )Nz<%s: %s>z(comment not loaded))r   )r   r   r   r   __repr__o   s    zMIMEtype.__repr__N)__name__
__module____qualname____doc__r   r(   r*   r.   r3   r4   r5   r   r   r   r   r   <   s   
r   c               @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )	MagicRulec       	      C   s  d | _ d | _d}x |jd}|dkr&P ||7 }qW |s>d| _nt|jd| _d}x |jd}|dkrhP ||7 }qTW t|jd| _|jd}|jd}t|t|d>  | _|j| j| _	|jd}|dkr|j| j| _
|jd}nd | _
|d	krRd}xB|d
kr>|dkr>|jd}|d
ks0|dkr2P ||7 } qW t|jd| _nd| _|d
krd}x.|dkr|jd}|dkrP ||7 }qhW t|jd| _nd| _|dkrtdd S )N    r      >r   ascii   =      &   ~   +   
zMalformed MIME magic line)nextprevreadnestintdecodestartordlenvaluevaluemaskwordrange
ValueError)	r   fZindcrJ   ZhbZlbwrr   r   r   r   s   s^    










zMagicRule.__init__c             C   s   | j | j | j S )N)rJ   rL   rP   )r   r   r   r   	getLength   s    zMagicRule.getLengthc             C   s0   | j |j k r|| _| |_n| jr,| jj| d S )N)rG   rD   rE   
appendRule)r   ruler   r   r   rW      s
    zMagicRule.appendRulec             C   s$   | j |r | jr| jj|S dS d S )NT)match0rD   match)r   bufferr   r   r   rZ      s    
zMagicRule.matchc       	      C   s   t |}xt| jD ]}| j| }|| j }||k r8dS | jrd}xft| jD ]J}trn|||  | j| @ }nt|||  t| j| @ }|t|7 }qNW n||| }|| jkrdS qW d S )NFr   T)	lenrP   rJ   rL   rN   PY3rK   chrrM   )	r   r[   lor-   eZtestirS   r   r   r   rY      s     


zMagicRule.match0c             C   s$   d| j | j| j| j| j| j| jf S )Nz!<MagicRule %d>%d=[%d]%r&%r~%d+%d>)rG   rJ   rL   rM   rN   rO   rP   )r   r   r   r   r5      s    zMagicRule.__repr__N)	r6   r7   r8   r   rV   rW   rZ   rY   r5   r   r   r   r   r:   r   s   @r:   c               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
	MagicTypec             C   s   || _ g | _d | _d S )N)mtype	top_rules	last_rule)r   rd   r   r   r   r      s    zMagicType.__init__c             C   s8   t |}|jr"| jr"| jj| n| jj| || _|S )N)r:   rG   rf   rW   re   append)r   rR   Znruler   r   r   getLine   s    zMagicType.getLinec             C   s$   x| j D ]}|j|r| jS qW d S )N)re   rZ   rd   )r   r[   rX   r   r   r   rZ      s    
zMagicType.matchc             C   s
   d| j  S )Nz<MagicType %s>)rd   )r   r   r   r   r5      s    zMagicType.__repr__N)r6   r7   r8   r   rh   rZ   r5   r   r   r   r   rc      s   rc   c               @   s8   e Zd Zdd Zdd ZdddZdd	d
Zdd ZdS )MagicDBc             C   s   i | _ d| _d S )Nr   )r   maxlen)r   r   r   r   r      s    zMagicDB.__init__c             C   sF  t |d0}|j }|dkr&tdx|j jd}|s>P |d dksZ|dd  dkrbtd	|d
d jd\}}t|}t|}y| j| }W n   g }|| j|< Y nX t	|}	|j
d
}
|jdd
 xR|
o|
dkr"|	j|}|r
|j | jkr
|j | _|j
d
}
|jdd
 qW |j|	 |
s*P q*W W d Q R X d S )Nrbs   MIME-Magic 
zNot a MIME magic filer=   r   [r   z]
zMalformed section headingr   :   [ro   rp   )openreadlineIOErrorrI   rQ   r   rH   r   r   rc   rF   seekrh   rV   rj   rg   )r   fnamerR   lineZsheadZpriZtnamerd   ZentsZ	magictyperS   rX   r   r   r   	mergeFile  s<    




zMagicDB.mergeFiled   r   c             C   sZ   xTt | jj ddD ]>}||kr"q||k r,P x$| j| D ]}|j|}|r8|S q8W qW d S )NT)reverse)sortedr   keysrZ   )r   datamax_primin_priZprioritytypemr   r   r   
match_data-  s    
zMagicDB.match_datac             C   sB   y0t |d}|j| j}W d Q R X | j|||S    Y nX d S )Nrk   )rq   rF   rj   r   )r   r!   r}   r~   rR   Zbufr   r   r   rZ   9  s    zMagicDB.matchc             C   s
   d| j  S )Nz<MagicDB %s>)r   )r   r   r   r   r5   A  s    zMagicDB.__repr__N)rx   r   )rx   r   )r6   r7   r8   r   rw   r   rZ   r5   r   r   r   r   ri      s
   ,

ri   textZplaininodeZblockdeviceZ
chardeviceZ	directoryZfifoZsocketsymlinkZdoorapplication
executableFc              C   sP  da i ag ai ai attat a	dd } x$t
jtjjddD ]}| | q@W x&t
jtjjddD ]}t	j| qfW tjdd d	 x\t
jtjjdd
D ]D}t|d0}x(|D ] }|j jd d\}}|t|< qW W d Q R X qW xdt
jtjjddD ]L}t|d8}x0|D ](}|j jd d\}}t| j| qW W d Q R X qW d S )NTc             S   s   t | }x|D ]}|jdr q|dd
 }|jdd\}}t|}|jdr|dd }d|kppd|kppd	|ks|tkr|t|< qd|ksd|ksd	|krtj||f q|t|< qW W dQ R X dS )z6Loads name matching information from a MIME directory.#Nr   rm   z*.r   *rl   ?rp   )rq   
startswithr   r   extsglobsrg   literals)r!   rR   rv   Z	type_namepatternrd   restr   r   r   _import_glob_file^  s     


 
z*_cache_database.<locals>._import_glob_filer   r   magicc             S   s   t | d S )Nr   )r\   )xr   r   r   <lambda>y  s    z!_cache_database.<locals>.<lambda>)keyr,   rU   r   Z
subclasses)_cache_uptodater   r   r   r,   r   r1   r2   ri   r   r   r"   r    r!   r   rw   sortrq   r   r   add)r   r!   rR   rv   aliasr.   subparentr   r   r   _cache_databaseR  s.    

r   c               C   s   t s
t  d S )N)r   r   r   r   r   r   r+     s    r+   c             C   s   t   tjj| }|tkr"t| S |j }|tkr:t| S |}x8|jd}|dk rTP ||d d }|tkr@t| S q@W |}x8|jd}|dk rP ||d d }|tkr~t| S q~W x0tD ](\}}t	j	||r|S t	j	||r|S qW dS )z6Returns type of file by its name, or None if not known.r   r   N)
r+   r    r!   basenamer   lowerfindr   r   fnmatch)r!   ZleafZlleafZextpglobZ	mime_typer   r   r   get_type_by_name  s:    
 
 r   rx   c             C   s   t   tj| ||S )z:Returns type of file by its contents, or None if not known)r+   r   rZ   )r!   r}   r~   r   r   r   get_type_by_contents  s    r   c             C   s   t   tj| ||S )z0Returns type of the data, which should be bytes.)r+   r   r   )r|   r}   r~   r   r   r   get_type_by_data  s    r   Tc          
   C   s   t   y|rtj| }n
tj| }W n   t| }|p:tS tj|jrt| |d}|s`t| }|spt| |d}|dkrtj	|jd@ rt
S tS |S tj|jrtS tj|jrtS tj|jrtS tj|jrtS tj|jrtS tj|j rtS tS )a  Returns type of file indicated by path.
    
    path :
      pathname to check (need not exist)
    follow :
      when reading file, follow symbolic links
    name_pri :
      Priority to do name matches.  100=override magic
    
    This tries to use the contents of the file, and falls back to the name. It
    can also handle special filesystem objects like directories and sockets.
    )r~   )r}   NI   )r+   r    statlstatr   r   S_ISREGst_moder   S_IMODEapp_exeS_ISDIR	inode_dirS_ISCHR
inode_charS_ISBLKinode_blockS_ISFIFO
inode_fifoS_ISLNKinode_symlinkS_ISSOCKinode_socket
inode_door)r!   ZfollowZname_pristr/   r   r   r   get_type  s@            r   c       	   
   C   s   | d7 } t |j }tjjdd}tjj|| }x>tj|D ]0}yt |j }W n   w<Y nX ||kr<dS q<W datjjtj|| }t |dj	| d}tj
tj||tjdrtj| td| dS )	a  Copy 'package_file' as ``~/.local/share/mime/packages/<application>.xml.``
    If package_file is None, install ``<app_dir>/<application>.xml``.
    If already installed, does nothing. May overwrite an existing
    file with the same name (if the contents are different)z.xmlr   ZpackagesNFrT   zupdate-mime-databasezThe '%s' command returned an error code!
Make sure you have the freedesktop.org shared MIME package:
http://standards.freedesktop.org/shared-mime-info/)rq   rF   r    r!   r   r   r"   r   Zsave_data_pathwritespawnlpP_WAITunlink	Exception)	r   Zpackage_fileZnew_dataZpackage_dirr&   r   Zold_dataZnew_fileZcommandr   r   r   install_mime_info  s&    
r   )N)rx   r   )rx   r   )Trx   ),r9   r    r   sysr   r%   r   Z
xdg.LocaleZxml.domr   r   collectionsr   r$   r   r   r   r   r   version_infor]   r   r   r   r:   rc   ri   r   r   r   r   r   r   r   r   r   r   r   r+   r   r   r   r   r   r   r   r   r   <module>   sL   
6pJ








7!


*