B
    ç¹`ñ  ã               @   sl   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m	Z	 ddl
mZ G dd„ deje	ƒZdS )é    Né   )ÚPY2)ÚIFileMonitor)Úget_watchman_sockpathc                   sŒ   e Zd ZdZd‡ fdd„	Zdd„ Z‡ fd	d
„Z‡ fdd„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd dd„Z‡  ZS )!ÚWatchmanFileMonitorz¼
    An :class:`hupper.interfaces.IFileMonitor` that uses Facebook's
    ``watchman`` daemon to detect changes.

    ``callback`` is a callable that accepts a path to a changed file.

    NÚwatchmanç      ð?c                sZ   t t| ƒ ¡  || _|| _tƒ | _tƒ | _t 	¡ | _
d| _|| _|| _|| _t ¡ | _d S )NT)Úsuperr   Ú__init__ÚcallbackÚloggerÚsetÚwatchesÚpathsÚ	threadingÚLockÚlockÚenabledÚsockpathÚbinpathÚtimeoutÚqueueÚQueueÚ	responses)Úselfr   r   r   r   r   Úkw)Ú	__class__© úW/home/kop/projects/devel/pgwui/test_venv/lib/python3.7/site-packages/hupper/watchman.pyr
      s    	
zWatchmanFileMonitor.__init__c          	   C   sl   | j \ tj |¡}x2| jD ]}||ks8| |tj ¡rP qW |  |¡ || jkr^| j 	|¡ W d Q R X d S )N)
r   ÚosÚpathÚdirnamer   Ú
startswithÚsepÚ_watchr   Úadd)r   r    ÚrootÚwatchr   r   r   Úadd_path,   s    

zWatchmanFileMonitor.add_pathc                sx   |   ¡ }t tjtj¡}| | j¡ | |¡ || _g | _|  	dg¡ |  
¡ }| j d|d  d ¡ tt| ƒ ¡  d S )NÚversionzConnected to watchman vÚ.)Ú_resolve_sockpathÚsocketÚAF_UNIXÚSOCK_STREAMÚ
settimeoutr   ÚconnectÚ_sockÚ	_recvbufsÚ_sendÚ_recvr   Údebugr	   r   Ústart)r   r   ÚsockÚresult)r   r   r   r6   8   s    
zWatchmanFileMonitor.startc                s&   zt t| ƒ ¡ S | j ¡  d | _X d S )N)r	   r   Újoinr1   Úclose)r   )r   r   r   r9   F   s    
zWatchmanFileMonitor.joinc          	   C   sð   xê| j rêy|  ¡ }W n tjk
r,   wY nX d|krJ| j d|d  ¡ d|krf| j d|d  ¡ d|krÒ|d }|d }| jH x@|D ]8}t|tƒr¢|d }t	j
 ||¡}|| jkrŒ|  |¡ qŒW W d Q R X |  |¡s| j |¡ qW d S )	NÚwarningzwatchman warning: Úerrorzwatchman error: Úsubscriptionr&   ÚfilesÚname)r   r4   r,   r   r   r<   r   Ú
isinstanceÚdictr   r    r9   r   r   Ú_is_unilateralr   Úput)r   r8   r&   r>   Úfr    r   r   r   ÚrunM   s*    



zWatchmanFileMonitor.runc             C   s2   d|kr|d rdS xdD ]}||krdS qW dS )NZ
unilateralT)Úlogr=   Fr   )r   r8   Úkr   r   r   rB   h   s    
z"WatchmanFileMonitor._is_unilateralc             C   s
   d| _ d S )NF)r   )r   r   r   r   Ústopq   s    zWatchmanFileMonitor.stopc             C   s   | j r| j S t| jƒS )N)r   r   r   )r   r   r   r   r+   t   s    z%WatchmanFileMonitor._resolve_sockpathc          	   C   s€   |   d|g¡}|d |kr"|d }| j d| ¡ |   d|d t ¡ t| ƒ|¡tt ¡ d ƒddgd	gd
œg¡ | j	 
|¡ d S )Nzwatch-projectr'   zWatchman is tracking root: Ú	subscribez{}.{}.{}r   ÚtyperD   r?   )ZsinceZ
expressionÚfields)Ú_queryr   r5   Úformatr   ÚgetpidÚidÚintÚtimer   r%   )r   r&   r8   r   r   r   r$   y   s    zWatchmanFileMonitor._watchc             C   s    t | jƒdkr>d| jd kr>| jd  dd¡\}}|g| _|S x\| j d¡}|sXtdƒ‚d|krŒd | j¡}| dd¡\}}|g| _|| S | j |¡ q@W d S )Nr   ó   
r   i   zlost connection to watchmanó    )Úlenr2   Úsplitr1   ÚrecvÚRuntimeErrorr9   Úappend)r   ÚlineÚbr8   r   r   r   Ú	_readlineŽ   s    zWatchmanFileMonitor._readlinec             C   sF   |   ¡ }ts| d¡}y
t |¡S  tk
r@   | j d¡ i S X d S )NÚutf8z)Ignoring corrupted payload from watchman.)r[   r   ÚdecodeÚjsonÚloadsÚ	Exceptionr   Úinfo)r   rY   r   r   r   r4       s    

zWatchmanFileMonitor._recvc             C   s,   t  |¡}ts| d¡}| j |d ¡ d S )NÚasciirR   )r^   Údumpsr   Úencoder1   Úsendall)r   ÚmsgÚcmdr   r   r   r3   ª   s    

zWatchmanFileMonitor._sendc             C   s   |   |¡ | jj|dS )N)r   )r3   r   Úget)r   rf   r   r   r   r   rL   °   s    
zWatchmanFileMonitor._query)Nr   r   )N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r(   r6   r9   rE   rB   rH   r+   r$   r[   r4   r3   rL   Ú__classcell__r   r   )r   r   r      s      	
r   )r^   r   r   r,   r   rQ   Úcompatr   Z
interfacesr   Úutilsr   ÚThreadr   r   r   r   r   Ú<module>   s   