o
    9A_.  ã                   @   s¨   d Z ddlZddlZddlZddlZddlZejjdk r!ddlZnddlm	Z	 zddl
Z
W n ey8   dZ
Y nw e d¡ZG dd„ deƒZG dd	„ d	eƒZd
d„ ZdS )zÇ
    livereload.watcher
    ~~~~~~~~~~~~~~~~~~

    A file watch management for LiveReload Server.

    :copyright: (c) 2013 - 2015 by Hsiaoming Yang
    :license: BSD, see LICENSE for more details.
é    Né   )Ú	signatureÚ
livereloadc                   @   sz   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zddd„Zdd„ Z	dd„ Z
ddd„Zdd„ Zddd„Zddd„Zddd„Zd
S )ÚWatcherzA file watcher registry.c                 C   s6   i | _ i | _i | _g | _d | _t ¡ | _g d¢| _d S )N)z.gitz.hgz.svnz.cvs)Ú_tasksÚ_task_mtimesÚ_new_mtimesÚ_changesÚfilepathÚtimeÚ_startÚignored_dirs©Úself© r   ú4/usr/lib/python3/dist-packages/livereload/watcher.pyÚ__init__!   s   
zWatcher.__init__c                 G   s   | j  |¡ d S ©N)r   Úextend)r   Úargsr   r   r   Úignore_dirs3   s   zWatcher.ignore_dirsc                 G   s   |D ]}| j  |¡ qd S r   )r   Úremove)r   r   Úar   r   r   Úremove_dirs_from_ignore6   s   ÿzWatcher.remove_dirs_from_ignorec                 C   s   t j |¡\}}|dv S )zIgnore a given filename or not.)z.pycz.pyoz.oz.swp)ÚosÚpathÚsplitext)r   ÚfilenameÚ_Úextr   r   r   Úignore:   s   zWatcher.ignoreNr   c                 C   s   |||i dœ| j |< dS )aí  Add a task to watcher.

        :param path: a filepath or directory path or glob pattern
        :param func: the function to be executed when file changed
        :param delay: Delay sending the reload message. Use 'forever' to
                      not send it. This is useful to compile sass files to
                      css, but reload on changed css files then only.
        :param ignore: A function return True to ignore a certain pattern of
                       filepath.
        )ÚfuncÚdelayr    ÚmtimesN)r   )r   r   r!   r"   r    r   r   r   Úwatch?   s
   üzWatcher.watchc                 C   s   dS )zƒStart the watcher running, calling callback when changes are
        observed. If this returns False, regular polling will be used.Fr   )r   Úcallbackr   r   r   ÚstartQ   s   zWatcher.startc           	      C   s  | j r| j  ¡ S d| _tƒ }| jD ]k}| j| }|d | _|  ||d ¡}|r||d }|d }|r;t|tƒr;| 	|¡ |r|t
|ddƒ}|sKt
|ddƒ}t d	 ||¡¡ tjjd
k rdtt |¡d ƒ}ntt|ƒjƒ}|dkryt|tƒry||ƒ q|ƒ  q|r„t|ƒ}nd}| j|fS )zCheck if there are changes. If so, run the given task.

        Returns a tuple of modified filepath and reload delay.
        Nr#   r    r!   r"   ÚnameÚ__name__Ú	anonymouszRunning task: {} (delay: {})r   r   )r	   Úpopr
   Úsetr   r   Ú
is_changedÚ
isinstanceÚfloatÚaddÚgetattrÚloggerÚinfoÚformatÚsysÚversion_infoÚmajorÚlenÚinspectÚ
getargspecr   Ú
parametersÚlistÚmax)	r   Údelaysr   ÚitemÚchangedr!   r"   r'   Úsig_lenr   r   r   ÚexamineV   s>   





ÿ
€

zWatcher.examinec                 C   sh   i | _ d}tj |¡r|  ||¡}ntj |¡r|  ||¡}n|  ||¡}|s+|  ¡ }| j	 
| j ¡ |S )z‰Check if any filepaths have been added, modified, or removed.

        Updates filepath modification times in self._task_mtimes.
        F)r   r   r   ÚisfileÚis_file_changedÚisdirÚis_folder_changedÚget_changed_glob_filesÚis_file_removedr   Úupdate)r   r   r    r?   r   r   r   r,      s   zWatcher.is_changedc                 C   s<   t | jƒt | jƒ }|sdS |D ]}| j |¡ || _qdS )z²Check if any filepaths have been removed since last check.

        Deletes removed paths from self._task_mtimes.
        Sets self.filepath to one of the removed paths.
        FT)r+   r   r   r*   r
   )r   Úremoved_pathsr   r   r   r   rG   ”   s   zWatcher.is_file_removedc                 C   sŽ   t j |¡sdS |  |¡rdS |r||ƒrdS t j |¡}|| jvr/|| j|< || _|| jkS | j| |kr@|| j|< || _dS || j|< dS )zµCheck if filepath has been added or modified since last check.

        Updates filepath modification times in self._new_mtimes.
        Sets self.filepath to changed path.
        FT)	r   r   rB   r    Úgetmtimer   r   r
   r   )r   r   r    Úmtimer   r   r   rC   ¥   s"   





zWatcher.is_file_changedc                 C   sd   t j|dd�D ](\}}}| jD ]}||v r| |¡ q|D ]}|  t j ||¡|¡r.  dS qqdS )z2Check if directory path has any changed filepaths.T)ÚfollowlinksF)r   Úwalkr   r   rC   r   Újoin)r   r   r    ÚrootÚdirsÚfilesÚdÚfr   r   r   rE   Ã   s   

€ÿÿzWatcher.is_folder_changedc                    sN   t jd dkrt jd dkrtj|dd�}nt |¡}‡ ‡fdd„|D ƒ}|S )	z-Check if glob path has any changed filepaths.r   r   é   é   T)Ú	recursivec                    s   g | ]
}ˆ  |ˆ ¡r|‘qS r   )rC   )Ú.0rS   ©r    r   r   r   Ú
<listcomp>Õ   s    z2Watcher.get_changed_glob_files.<locals>.<listcomp>)r4   r5   Úglob)r   r   r    rQ   Úchanged_filesr   rX   r   rF   Ï   s
   
zWatcher.get_changed_glob_files)Nr   Nr   )r(   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r    r$   r&   rA   r,   rG   rC   rE   rF   r   r   r   r   r      s    

)

r   c                   @   s.   e Zd Zdd„ Zd
dd„Zdd„ Zdd	„ ZdS )ÚINotifyWatcherc                 C   s$   t  | ¡ t ¡ | _d | _d | _d S r   )r   r   Ú	pyinotifyÚWatchManagerÚwmÚnotifierr%   r   r   r   r   r   Ú   s   


zINotifyWatcher.__init__Nc                 C   s>   t jt jB t jB }| jj||dddd� t | ||||¡ d S )NT)ÚrecÚdo_globÚauto_add)r`   Ú	IN_CREATEÚ	IN_DELETEÚ	IN_MODIFYrb   Ú	add_watchr   r$   )r   r   r!   r"   r    Úflagr   r   r   r$   á   s   zINotifyWatcher.watchc                 C   s   |   ¡  d S r   )r%   )r   Úeventr   r   r   Úinotify_eventæ   s   zINotifyWatcher.inotify_eventc                 C   s>   | j s|| _ddlm} tj| j|j ¡ | j	d�| _ |ƒ  dS )Nr   )Úioloop)Údefault_proc_funT)
rc   r%   Útornadorn   r`   ÚTornadoAsyncNotifierrb   ÚIOLoopÚinstancerm   )r   r%   rn   r   r   r   r&   é   s   þzINotifyWatcher.start)NNN)r(   r\   r]   r   r$   rm   r&   r   r   r   r   r_   Ù   s
    
r_   c                   C   s   t d u s	tt dƒstS tS )Nrq   )r`   Úhasattrr   r_   r   r   r   r   Úget_watcher_classö   s   ru   )r^   rZ   Úloggingr   r   r4   r5   r6   r8   r   r`   ÚImportErrorÚ	getLoggerr1   Úobjectr   r_   ru   r   r   r   r   Ú<module>   s&   

ÿ
 ;