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ddlZddlmZ ddlm	Z	 ddlm
Z
 ddlmZ ddlmZ ddlmZ e d	¡ZG d
d„ deƒZG dd„ dejƒZG dd„ dejƒZG dd„ dejƒZG dd„ deƒZdS )z¿
    livereload.handlers
    ~~~~~~~~~~~~~~~~~~~

    HTTP and WebSocket handlers for livereload.

    :copyright: (c) 2013 by Hsiaoming Yang
    :license: BSD, see LICENSE for more details.
é    N)Úweb)Úioloop)Úescape)Úgen_log)ÚWebSocketHandler)Ú
ObjectDictÚ
livereloadc                   @   sl   e Zd Zeƒ ZdZdZdZdd„ Zdd„ Z	dd„ Z
dd	„ Zed
d„ ƒZedd„ ƒZeddd„ƒZdd„ ZdS )ÚLiveReloadHandlerNc                 C   ó   dS ©NT© ©Úselfr   r   ú5/usr/lib/python3/dist-packages/livereload/handlers.pyÚallow_draft76!   ó   zLiveReloadHandler.allow_draft76c                 C   r
   r   r   )r   Úoriginr   r   r   Úcheck_origin$   r   zLiveReloadHandler.check_originc                 C   s   | t jv rt j | ¡ d S d S ©N)r	   ÚwaitersÚremover   r   r   r   Úon_close'   s   
ÿzLiveReloadHandler.on_closec                 C   s@   t |tƒr
t |¡}z|  |¡ W d S    tjddd� Y d S )NúError sending messageT©Úexc_info)Ú
isinstanceÚdictr   Újson_encodeÚwrite_messageÚloggerÚerror)r   Úmessager   r   r   Úsend_message+   s   

zLiveReloadHandler.send_messagec                 C   sr   | j rd S | jjst d¡ | j t ¡ ¡ t ¡ | _ t d¡ | j 	| j
¡s7t d¡ t | j
d¡ 	¡  d S d S )NzWatch current working directoryzStart watching changeszStart detecting changesi   )Ú_last_reload_timeÚwatcherÚ_tasksr   ÚinfoÚwatchÚosÚgetcwdÚtimeÚstartÚ
poll_tasksr   ÚPeriodicCallback©Úclsr   r   r   Ústart_tasks4   s   



þzLiveReloadHandler.start_tasksc                 C   s”   | j  ¡ \}}|r|dks| jsd S d}|rtd| dƒ}|dkr#d}t ¡ | j |k r4t d|¡ d S |rDtj	 
¡ }| || j¡ d S |  ¡  d S )NÚforeveré   é   Ú__livereload__r   z
Ignore: %s)r$   Úexaminer   Úmaxr*   r#   r   r&   r   ÚIOLoopÚcurrentÚ
call_laterÚreload_waiters)r/   ÚfilepathÚdelayÚreload_timeÚloopr   r   r   r,   C   s   
zLiveReloadHandler.poll_tasksc                 C   sŒ   t  dt| jƒ| jj¡ |d u r| jjpd}d|| jddœ}t ¡ | _| j 	¡ D ]}z| 
|¡ W q(   t jddd� | j |¡ Y q(d S )NzReload %s waiters: %sÚ*ÚreloadT)ÚcommandÚpathÚliveCSSÚliveImgr   r   )r   r&   Úlenr   r$   r;   Úlive_cssr*   r#   Úcopyr   r    r   )r/   rB   ÚmsgÚwaiterr   r   r   r:   Z   s(   ýü
ûz LiveReloadHandler.reload_waitersc                 C   sj   t t |¡ƒ}|jdkrddgddœ}|  |¡ |jdkr1d|v r3t d|j ¡ tj	 
| ¡ dS dS dS )	zƒHandshake with livereload.js

        1. client send 'hello'
        2. server reply 'hello'
        3. client send 'info'
        Úhelloz*http://livereload.com/protocols/official-7zlivereload-tornado)rA   Ú	protocolsÚ
serverNamer&   ÚurlzBrowser Connected: %sN)r   r   Újson_decoderA   r"   r   r&   rM   r	   r   Úadd)r   r!   Ú	handshaker   r   r   Ú
on_messaget   s   
ÿû
þzLiveReloadHandler.on_messager   )Ú__name__Ú
__module__Ú__qualname__Úsetr   r$   rF   r#   r   r   r   r"   Úclassmethodr0   r,   r:   rQ   r   r   r   r   r	      s     	

r	   c                   @   s4   e Zd Zi Zedd„ ƒZedd„ ƒZedd„ ƒZdS )ÚMtimeStaticFileHandlerc                 C   s    t  |¡}tj |tj ¡}|S )z¥Returns the time that ``abspath`` was last modified.

        May be overridden in subclasses.  Should return a `~datetime.datetime`
        object or None.
        )r(   ÚstatÚdatetimeÚutcfromtimestampÚST_MTIME)r/   ÚabspathÚstat_resultÚmodifiedr   r   r   Úget_content_modified_timeŽ   s
   
ÿz0MtimeStaticFileHandler.get_content_modified_timec                 C   sh   |   |¡}t ¡ }t|  |¡dƒ}| | ¡ ¡ t|tƒr&| |¡ | 	¡ S |D ]}| |¡ q(| 	¡ S )zæReturns a version string for the resource at the given path.

        This class method may be overridden by subclasses.  The
        default implementation is a hash of the file's contents.

        .. versionadded:: 3.1
        z%Y-%m-%d %H:%M:%S)
Úget_contentÚhashlibÚmd5Úformatr_   ÚupdateÚencoder   ÚbytesÚ	hexdigest)r/   r\   ÚdataÚhasherÚ
mtime_dataÚchunkr   r   r   Úget_content_versionš   s   
	

þz*MtimeStaticFileHandler.get_content_versionc                    s¾   ‡ fdd„}ˆ j �L ˆ j}ˆ j}||vr#||ƒ\}}|||< |||< n| |¡}| |¡}|ˆ  |¡krB||ƒ\}}|||< |||< |rM|W  d   ƒ S W d   ƒ d S 1 sXw   Y  d S )Nc                    s@   zˆ   | ¡}ˆ  | ¡}||fW S  ty   t d| ¡ Y dS w )NzCould not open static file %r)NN)rl   r_   Ú	Exceptionr   r    )Úabs_pathÚhshÚmtmr.   r   r   Ú_load_version³   s   


þzAMtimeStaticFileHandler._get_cached_version.<locals>._load_version)Ú_lockÚ_static_hashesÚ_static_mtimesÚgetr_   )r/   rn   rq   ÚhashesÚmtimesrp   ro   r   r.   r   Ú_get_cached_version±   s,   



ì
íëz*MtimeStaticFileHandler._get_cached_versionN)rR   rS   rT   rt   rV   r_   rl   rx   r   r   r   r   rW   ‹   s    

rW   c                   @   ó   e Zd Zdd„ ZdS )ÚLiveReloadJSHandlerc                 C   sl   |   dd¡ tj tj t¡¡}tj |d¡}t|dƒ�}|  | 	¡ ¡ W d   ƒ d S 1 s/w   Y  d S )NzContent-Typezapplication/javascriptzvendors/livereload.jsÚrb)
Ú
set_headerr(   rB   r\   ÚdirnameÚ__file__ÚjoinÚopenÚwriteÚread)r   ÚrootÚjs_fileÚfr   r   r   ru   ×   s   "ÿzLiveReloadJSHandler.getN©rR   rS   rT   ru   r   r   r   r   rz   Õ   s    rz   c                   @   ry   )ÚForceReloadHandlerc                 C   s*   | j dd d�pd}t |¡ |  d¡ d S )NrB   )Údefaultr?   Úok)Úget_argumentr	   r:   r�   )r   rB   r   r   r   ru   à   s   
zForceReloadHandler.getNr†   r   r   r   r   r‡   ß   ó    r‡   c                   @   ry   )ÚStaticFileHandlerc                 C   r
   )NFr   r   r   r   r   Úshould_return_304ç   r   z#StaticFileHandler.should_return_304N)rR   rS   rT   r�   r   r   r   r   rŒ   æ   r‹   rŒ   )Ú__doc__rY   ra   r(   rX   r*   ÚloggingÚtornador   r   r   Útornado.logr   Útornado.websocketr   Útornado.utilr   Ú	getLoggerr   r	   rŒ   rW   ÚRequestHandlerrz   r‡   r   r   r   r   Ú<module>   s&   	
pJ
