o
    Pa@[…3  ã                   @   sö   d dl Z d dl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
Z	dZdZdZe  e¡Ze dg d¢¡Ze e¡Zeeej dd	¡ƒƒZG d
d„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZ G dd„ deƒZ!dS )é    N)ÚEINTRé   ZiIII)ZIN_Q_OVERFLOWZ
IN_UNMOUNTÚ_INOTIFY_EVENT)ÚwdÚmaskZcookieÚlenÚDEBUGÚ0c                   @   s   e Zd ZdS )ÚEventTimeoutExceptionN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú4usr/lib/python3.10/site-packages/inotify/adapters.pyr
   (   s    r
   c                       s   e Zd Z‡ fdd„Z‡  ZS )ÚTerminalEventExceptionc                    s   t t| ƒ |¡ || _d S ©N)Úsuperr   Ú__init__Úevent)ÚselfÚ	type_namer   ©Ú	__class__r   r   r   -   s   
zTerminalEventException.__init__)r   r   r   r   Ú__classcell__r   r   r   r   r   ,   s    r   c                   @   s|   e Zd Zg efdd„Zdd„ Zdd„ Zejj	fdd„Z
dd
d„Zddd„Zdd„ Zdd„ Zdddefdd„Zedd„ ƒZdS )ÚInotifyc                 C   sl   || _ i | _i | _d| _tj ¡ | _t 	d| j¡ t
 ¡ | _| j | jt
j¡ d | _|D ]}|  |¡ q,d S )Nó    zInotify handle is (%d).)Ú_Inotify__block_durationÚ_Inotify__watchesÚ_Inotify__watches_rÚ_Inotify__bufferÚinotifyÚcallsZinotify_initÚ_Inotify__inotify_fdÚ_LOGGERÚdebugÚselectÚepollÚ_Inotify__epollÚregisterÚPOLLINÚ_Inotify__last_success_returnÚ	add_watch)r   ÚpathsÚblock_duration_sÚpathr   r   r   r   3   s   
ÿzInotify.__init__c                 C   s$   z|   ¡ W S  ty   | j  Y S w )z=Allow the block-duration to be an integer or a function-call.)r   Ú	TypeError©r   r   r   r   Z__get_block_durationD   s
   

þzInotify.__get_block_durationc                 C   s   t  d¡ t | j¡ d S )NzCleaning-up inotify.)r#   r$   ÚosÚcloser"   r0   r   r   r   Ú__del__M   s   
zInotify.__del__c                 C   sh   t  d|¡ || jv rt  d|¡ d S | d¡}tj | j||¡}t  d||¡ || j|< || j	|< |S )NzAdding watch: [%s]z Path already being watched: [%s]Úutf8zAdded watch (%d): [%s])
r#   r$   r   ÚwarningÚencoder    r!   Zinotify_add_watchr"   r   )r   Zpath_unicoder   Z
path_bytesr   r   r   r   r+   Q   s   



zInotify.add_watchFc                 C   s<   | j  |¡}|du rdS t d||¡ | j |= |  |¡ dS )zÙRemove our tracking information and call inotify to stop watching
        the given path. When a directory is removed, we'll just have to remove
        our tracking since inotify already cleans-up the watch.
        Nz*Removing watch for watch-handle (%d): [%s])r   Úgetr#   r$   Úremove_watch_with_id)r   r.   Úsuperficialr   r   r   r   Úremove_watchg   s   ÿzInotify.remove_watchc                 C   s4   | j |= |du rt d|¡ tj | j|¡ d S d S )NFz%Removing watch for watch-handle (%d).)r   r#   r$   r    r!   Zinotify_rm_watchr"   )r   r   r9   r   r   r   r8   x   s
   ýzInotify.remove_watch_with_idc                 C   sZ   g }t jj ¡ D ]\}}||@ r| |¡ ||8 }|dkr nq|dks+J d|f ƒ‚|S )Nr   z*We could not resolve all event-types: (%d))r    Ú	constantsZMASK_LOOKUPÚitemsÚappend)r   Ú
event_typeÚnamesÚbitÚnamer   r   r   Ú_get_event_names€   s   
€
ÿzInotify._get_event_namesc                 c   s   t  |d¡}|sdS |  j|7  _	 t| jƒ}|tk r#t d¡ dS | jdt… }t t	|¡}t
|Ž }|  |j¡}t d |¡¡ t|j }||k rMdS | jt|… }	|	 d¡}
| j|d… | _| j |j¡}|durx|
 d¡}||||fV  t| jƒ}|tk rƒdS q)z1Handle a series of events coming-in from inotify.i   Nr   zNot enough bytes for a header.zEvents received in stream: {}ó    r4   )r1   Úreadr   r   Ú_STRUCT_HEADER_LENGTHr#   r$   ÚstructÚunpackÚ_HEADER_STRUCT_FORMATr   rB   r   ÚformatÚrstripr   r7   r   Údecode)r   r   ÚbÚlengthZ
peek_sliceZ
header_rawÚheaderÚ
type_namesZevent_lengthÚfilenameZfilename_bytesr.   Zfilename_unicodeZbuffer_lengthr   r   r   Ú_handle_inotify_event   s@   €

þ



ÛzInotify._handle_inotify_eventNTc              
   c   sV   d| _ t ¡ }	 |  ¡ }z| j |¡}W n- tyB } z!|jtkr#‚ |dur8t ¡ | }	|	|kr8W Y d}~dS W Y d}~qd}~ww |D ]M\}
}|  |¡}t	 
d |¡¡ |  |
¡D ]6\}}}}t ¡ }||||f}|D ] }|dur„|||ƒdu r„||f| _    dS ||v rt||ƒ‚qm|V  q[qE|dur£t ¡ | }	|	|kr£dS |du rªdV  q	)zˆYield one event after another. If `timeout_s` is provided, we'll
        break when no event is received for that many seconds.
        NTzEvents received from epoll: {}F)r*   ÚtimeÚ_Inotify__get_block_durationr'   ÚpollÚIOErrorÚerrnor   rB   r#   r$   rI   rQ   r   )r   Z	timeout_sZyield_nonesZfilter_predicateZterminal_eventsZ
last_hit_sr-   ÚeventsÚeZtime_since_event_sÚfdr>   r?   rN   rO   r.   rP   r   r   r   r   Ú	event_gen¿   sR   €

€÷
ÿ


ÿóÑzInotify.event_genc                 C   ó   | j S r   )r*   r0   r   r   r   Úlast_success_returný   ó   zInotify.last_success_return©F)r   r   r   Ú_DEFAULT_EPOLL_BLOCK_DURATION_Sr   rS   r3   r    r;   ÚIN_ALL_EVENTSr+   r:   r8   rB   rQ   Ú_DEFAULT_TERMINAL_EVENTSrZ   Úpropertyr\   r   r   r   r   r   2   s    	

1
þ>r   c                   @   s4   e Zd Zejjefdd„Zd	dd„Ze	dd„ ƒZdS )
Ú	_BaseTreec                 C   s.   |t jjB t jjB t jjB | _t|d| _d S )N)r-   )r    r;   ÚIN_ISDIRÚ	IN_CREATEZ	IN_DELETEÚ_maskr   Ú_i)r   r   r-   r   r   r   r     s   ÿþýz_BaseTree.__init__Fc           	      k   s&   | j jd	i |¤ŽD ]†}|dur|\}}}}|jtjj@ rtj ||¡}|jtjj	@ s2|jtjj
@ rLtj |¡du s>|du rLt d|¡ | j  || j¡ |jtjj@ rbt d|¡ | j j|dd n+|jtjj@ rxt d|¡ | j j|dd n|jtjj	@ rt d|¡ | j  || j¡ |V  q
dS )
aJ  This is a secondary generator that wraps the principal one, and
        adds/removes watches as directories are added/removed.

        If we're doing anything funky and allowing the events to queue while a
        rename occurs then the folder may no longer exist. In this case, set
        `ignore_missing_new_folders`.
        NTFz^A directory has been created. We're adding a watch on it (because we're being recursive): [%s]zlA directory has been removed. We're being recursive, but it would have automatically been deregistered: [%s])r9   zlA directory has been renamed. We're being recursive, but it would have automatically been deregistered: [%s]z^A directory has been renamed. We're adding a watch on it (because we're being recursive): [%s]r   )rg   rZ   r   r    r;   rd   r1   r.   ÚjoinZIN_MOVED_TOre   Úexistsr#   r$   r+   rf   ZIN_MOVED_FROMr:   )	r   Zignore_missing_new_foldersÚkwargsr   rN   rO   r.   rP   Ú	full_pathr   r   r   rZ     sB   €	ÿþþýýþÔz_BaseTree.event_genc                 C   r[   r   )rg   r0   r   r   r   r    F  r]   z_BaseTree.inotifyNr^   )
r   r   r   r    r;   r`   r_   r   rZ   rb   r   r   r   r   rc     s    
ÿ
7rc   c                       ó2   e Zd ZdZejjef‡ fdd„	Zdd„ Z	‡  Z
S )ÚInotifyTreezRecursively watch a path.c                    s(   t t| ƒj||d || _|  |¡ d S ©N)r   r-   )r   rm   r   Z_InotifyTree__root_pathÚ_InotifyTree__load_tree)r   r.   r   r-   r   r   r   r   N  s   zInotifyTree.__init__c                 C   sŽ   t  d|¡ g }|g}|r8|d }|d= | |¡ t |¡D ]}tj ||¡}tj |¡du r0q| |¡ q|s|D ]
}| j 	|| j
¡ q:d S )Nz$Adding initial watches on tree: [%s]r   F)r#   r$   r=   r1   Úlistdirr.   rh   Úisdirrg   r+   rf   )r   r.   r,   ÚqÚcurrent_pathrP   Úentry_filepathr   r   r   Z__load_treeV  s    
õÿzInotifyTree.__load_tree)r   r   r   Ú__doc__r    r;   r`   r_   r   ro   r   r   r   r   r   rm   K  s    ÿrm   c                       rl   )ÚInotifyTreesz'Recursively watch over a list of trees.c                    s"   t t| ƒj||d |  |¡ d S rn   )r   rv   r   Ú_InotifyTrees__load_trees)r   r,   r   r-   r   r   r   r   p  s   zInotifyTrees.__init__c                 C   s˜   t  dd tt|ƒ¡¡ g }|}|r=|d }|d= | |¡ t |¡D ]}tj ||¡}tj 	|¡du r5q#| |¡ q#|s|D ]
}| j
 || j¡ q?d S )Nz%Adding initial watches on trees: [%s]ú,r   F)r#   r$   rh   ÚmapÚstrr=   r1   rp   r.   rq   rg   r+   rf   )r   r,   Úfoundrr   rs   rP   rt   r.   r   r   r   Z__load_treesv  s    
õÿzInotifyTrees.__load_trees)r   r   r   ru   r    r;   r`   r_   r   rw   r   r   r   r   r   rv   m  s    ÿrv   )"Úloggingr%   r1   rF   ÚcollectionsrR   rV   r   Zinotify.constantsr    Zinotify.callsr_   rH   ra   Ú	getLoggerr   r#   Ú
namedtupler   ÚcalcsizerE   ÚboolÚintÚenvironr7   Z	_IS_DEBUGÚ	Exceptionr
   r   Úobjectr   rc   rm   rv   r   r   r   r   Ú<module>   s4    
þ
	 QI"