U
    Âmœdg,  ã                
   @   s~  d Z ddlmZ ddlZddlmZ ddlZddlZddlm	Z	 ddl
Z
ddlZddlZddlZddlZzddlZW n, ek
r  Z zedƒe‚W 5 dZ[X Y nX 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m Z  ej! "d¡G dd„ dej#ƒƒZ$ej#dd„ d�Z%G dd„ dej&ƒZ&G dd„ dej'ƒZ(G dd„ dej)j*ƒZ+dd„ Z,ej-G dd„ deƒƒZ.dS )z8
Displays Agg images in the browser, with interactivity
é    )ÚcontextmanagerN)ÚBytesIO)ÚPathz$The WebAgg backend requires Tornado.)Ú_Backend)ÚGcfé   )Úbackend_webagg_core)ÚTimerAsyncioÚTimerTornadoz3.7c                   @   s   e Zd Zdd„ ZdS )ÚServerThreadc                 C   s   t jj ¡  ¡  d S ©N©ÚtornadoÚioloopÚIOLoopÚinstanceÚstart©Úself© r   ú[/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/matplotlib/backends/backend_webagg.pyÚrun-   s    zServerThread.runN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   +   s   r   c                   C   s   t jj ¡  ¡ S r   r   r   r   r   r   Ú<lambda>2   ó    r   )Útargetc                   @   s$   e Zd ZejZeddœdd„ƒZdS )ÚFigureManagerWebAggN)Úblockc                C   sd   t  ¡  djt jt jt jd�}tjd rJdd l}| 	|¡sXt
d |¡ƒ nt
d |¡ƒ t  ¡  d S )Nzhttp://{address}:{port}{prefix})ÚaddressÚportÚprefixzwebagg.open_in_browserr   zTo view figure, visit {0})ÚWebAggApplicationÚ
initializeÚformatr    r!   Ú
url_prefixÚmplÚrcParamsÚ
webbrowserÚopenÚprintr   )Úclsr   Úurlr)   r   r   r   Úpyplot_show8   s    ý

zFigureManagerWebAgg.pyplot_show)r   r   r   ÚcoreÚNavigationToolbar2WebAggZ_toolbar2_classÚclassmethodr.   r   r   r   r   r   5   s   r   c                   @   s   e Zd ZeZdS )ÚFigureCanvasWebAggN)r   r   r   r   Zmanager_classr   r   r   r   r2   K   s   r2   c                       s¸   e Zd ZdZdZG dd„ dejjƒZG dd„ dejjƒZ	G dd„ dejjƒZ
G dd	„ d	ejjƒZG d
d„ dejjƒZG dd„ dejjƒZd‡ fdd„	Zeddd„ƒZedd„ ƒZ‡  ZS )r#   Fc                   @   s   e Zd Zdd„ ZdS )zWebAggApplication.FavIconc                 C   s(   |   dd¡ |  tt ¡ dƒ ¡ ¡ d S )NúContent-Typez	image/pngzimages/matplotlib.png)Ú
set_headerÚwriter   r'   Úget_data_pathÚ
read_bytesr   r   r   r   ÚgetT   s    ÿzWebAggApplication.FavIcon.getN©r   r   r   r8   r   r   r   r   ÚFavIconS   s   r:   c                       s*   e Zd Zddœ‡ fdd„
Zdd„ Z‡  ZS )z"WebAggApplication.SingleFigurePageÚ ©r&   c                   s   || _ tƒ j||f|Ž d S r   ©r&   ÚsuperÚ__init__©r   ZapplicationÚrequestr&   Úkwargs©Ú	__class__r   r   r?   Z   s    z+WebAggApplication.SingleFigurePage.__init__c                 C   sF   t |ƒ}t |¡}dj| j| jd�}| jd| j||tjj	|j
d� d S )Núws://{req.host}{prefix}/©Úreqr"   zsingle_figure.html)r"   Úws_uriÚfig_idÚ	toolitemsÚcanvas)Úintr   Úget_fig_managerr%   rA   r&   Úrenderr/   r0   rJ   rK   )r   ÚfignumÚmanagerrH   r   r   r   r8   ^   s    
ÿúz&WebAggApplication.SingleFigurePage.get©r   r   r   r?   r8   Ú__classcell__r   r   rC   r   ÚSingleFigurePageY   s   rS   c                       s*   e Zd Zddœ‡ fdd„
Zdd„ Z‡  ZS )z WebAggApplication.AllFiguresPager;   r<   c                   s   || _ tƒ j||f|Ž d S r   r=   r@   rC   r   r   r?   m   s    z)WebAggApplication.AllFiguresPage.__init__c                 C   s:   dj | j| jd�}| jd| j|ttj ¡ ƒtj	j
d� d S )NrE   rF   zall_figures.html)r"   rH   ZfiguresrJ   )r%   rA   r&   rN   Úsortedr   ZfigsÚitemsr/   r0   rJ   )r   rH   r   r   r   r8   q   s    ÿûz$WebAggApplication.AllFiguresPage.getrQ   r   r   rC   r   ÚAllFiguresPagel   s   rV   c                   @   s   e Zd Zdd„ ZdS )zWebAggApplication.MplJsc                 C   s$   |   dd¡ tj ¡ }|  |¡ d S )Nr3   zapplication/javascript)r4   r/   r   Zget_javascriptr5   )r   Z
js_contentr   r   r   r8   |   s    
zWebAggApplication.MplJs.getNr9   r   r   r   r   ÚMplJs{   s   rW   c                   @   s   e Zd Zdd„ ZdS )zWebAggApplication.Downloadc                 C   sR   t |ƒ}t |¡}|  dtj |d¡¡ tƒ }|jj	j
||d� |  | ¡ ¡ d S )Nr3   Úbinary)r%   )rL   r   rM   r4   Ú	mimetypesÚ	types_mapr8   r   rK   ÚfigureZsavefigr5   Úgetvalue)r   rO   ÚfmtrP   Zbuffr   r   r   r8   „   s    
 ÿzWebAggApplication.Download.getNr9   r   r   r   r   ÚDownloadƒ   s   r^   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )zWebAggApplication.WebSocketTc                 C   s<   t |ƒ| _t | j¡| _| j | ¡ t| dƒr8|  d¡ d S )NÚset_nodelayT)rL   rO   r   rM   rP   Zadd_web_socketÚhasattrr_   )r   rO   r   r   r   r*   �   s
    

z WebAggApplication.WebSocket.openc                 C   s   | j  | ¡ d S r   )rP   Zremove_web_socketr   r   r   r   Úon_close—   s    z$WebAggApplication.WebSocket.on_closec                 C   sD   t  |¡}|d dkr"|d | _nt | j¡}|d k	r@| |¡ d S )NÚtypeÚsupports_binaryÚvalue)ÚjsonÚloadsrc   r   rM   rO   Zhandle_json)r   ÚmessagerP   r   r   r   Ú
on_messageš   s    
z&WebAggApplication.WebSocket.on_messagec                 C   s   |   t |¡¡ d S r   )Úwrite_messagere   Údumps)r   Úcontentr   r   r   Ú	send_json©   s    z%WebAggApplication.WebSocket.send_jsonc                 C   s<   | j r| j|dd� n"d | d¡ dd¡¡}|  |¡ d S )NT)rX   zdata:image/png;base64,{0}Úbase64Ú
r;   )rc   ri   r%   ÚencodeÚreplace)r   ZblobZdata_urir   r   r   Úsend_binary¬   s    ÿz'WebAggApplication.WebSocket.send_binaryN)	r   r   r   rc   r*   ra   rh   rl   rq   r   r   r   r   Ú	WebSocket�   s   rr   r;   c              
      sÊ   |r$|d dkr|d dks$t dƒ‚tƒ j|d tjjdtj ¡ if|d tjjdt	t
 ¡ dƒif|d	 | jf|d
 | jd|if|d | jd|if|d | jf|d | jf|d | jfgtj ¡ d� d S )Nr   ú/éÿÿÿÿz6url_prefix must start with a "/" and not end with one.z/_static/(.*)Úpathz/_images/(.*)Zimagesz/favicon.icoz	/([0-9]+)r&   z/?z
/js/mpl.jsz/([0-9]+)/wsz/([0-9]+)/download.([a-z0-9.]+))Ztemplate_path)ÚAssertionErrorr>   r?   r   ÚwebZStaticFileHandlerr/   r   Úget_static_file_pathr   r'   r6   r:   rS   rV   rW   rr   r^   )r   r&   rC   r   r   r?   ´   s8    ÿþþ
ÿ
ÿÿã ßzWebAggApplication.__init__Nc                 C   sÄ   | j r
d S | |d�}|| _dd„ }|d kr8tjd | _n|| _tjd | _|| jtjd ƒD ]T}z| || j¡ W n2 tjk
r¤ } z|j	t	j
kr”‚ W 5 d }~X Y q\X || _ qºq\tdƒ‚d| _ d S )	Nr<   c                 s   sN   t td|ƒƒD ]}| | V  qt |d ƒD ]}| t d| d| ¡ V  q*dS )zâ
            Generate a list of n random ports near the given port.

            The first 5 ports will be sequential, and the remaining n-5 will be
            randomly selected in the range [port-2*n, port+2*n].
            é   éþÿÿÿé   N)ÚrangeÚminÚrandomÚrandint)r!   ÚnÚir   r   r   Úrandom_portsè   s    z2WebAggApplication.initialize.<locals>.random_portszwebagg.addresszwebagg.portzwebagg.port_retrieszSThe webagg server could not be started because an available port could not be foundT)Úinitializedr&   r'   r(   r    r!   ÚlistenÚsocketÚerrorÚerrnoÚ
EADDRINUSEÚ
SystemExit)r,   r&   r!   r    Zappr‚   Úer   r   r   r$   Ü   s.    
ÿÿzWebAggApplication.initializec              	      sœ   dd l }z| ¡  W n tk
r(   Y nX dˆ _ˆ jr:d S tjj ¡ ‰‡ ‡fdd„‰t‡‡fdd„ƒ}dˆ _t	dƒ t
j ¡  |ƒ � ˆ ¡  W 5 Q R X d S )Nr   Tc                      s$   ˆ  ¡  tdƒ tj ¡  dˆ _d S )NzServer is stoppedF)Ústopr+   ÚsysÚstdoutÚflushÚstartedr   )r,   r   r   r   Úshutdown   s    
z)WebAggApplication.start.<locals>.shutdownc               
   3   s8   t   t j‡ ‡fdd„¡} z
d V  W 5 t   t j| ¡ X d S )Nc                    s
   ˆ   ˆ¡S r   )Zadd_callback_from_signal)ÚsigÚframe©r   r�   r   r   r   *  r   z?WebAggApplication.start.<locals>.catch_sigint.<locals>.<lambda>)ÚsignalÚSIGINT)Zold_handlerr“   r   r   Úcatch_sigint&  s    þ
z-WebAggApplication.start.<locals>.catch_sigintz"Press Ctrl+C to stop WebAgg server)ÚasyncioÚget_running_loopÚRuntimeErrorr�   r   r   r   r   r   r+   rŒ   r�   rŽ   r   )r,   r—   r–   r   )r,   r   r�   r   r   
  s"    	

zWebAggApplication.start)r;   )r;   NN)r   r   r   rƒ   r�   r   rw   ZRequestHandlerr:   rS   rV   rW   r^   Z	websocketZWebSocketHandlerrr   r?   r1   r$   r   rR   r   r   rC   r   r#   O   s   
'(-r#   c                 C   s”   dd l }t ¡  dd l}z| ¡  W n$ tk
rH   t ¡ sDt ¡  Y nX | j	}t
tj ¡ dƒ ¡ }|j |¡}|jtj|tjj| jtjd� d¡S )Nr   zipython_inline_figure.html)r"   rI   rJ   rK   r!   zutf-8)Ztornado.templater#   r$   r—   r˜   r™   Úwebagg_server_threadÚis_aliver   Únumberr   r/   r   rx   Ú	read_textÚtemplateÚTemplateÚgenerater&   r0   rJ   rK   r!   Údecode)r[   r   r—   rO   ZtplÚtr   r   r   Úipython_inline_display9  s,    
ÿûûr£   c                   @   s   e Zd ZeZeZdS )Ú_BackendWebAggN)r   r   r   r2   ZFigureCanvasr   ZFigureManagerr   r   r   r   r¤   P  s   r¤   )/Ú__doc__Ú
contextlibr   r‡   Úior   re   rY   Úpathlibr   r~   rŒ   r”   r…   Ú	threadingr   ÚImportErrorÚerrr™   Ztornado.webZtornado.ioloopZtornado.websocketZ
matplotlibr'   Zmatplotlib.backend_basesr   Zmatplotlib._pylab_helpersr   r;   r   r/   r	   r
   Z_apiÚ
deprecatedÚThreadr   rš   r   ZFigureCanvasWebAggCorer2   rw   ÚApplicationr#   r£   Zexportr¤   r   r   r   r   Ú<module>   sF   
ÿ k