U
    Fvfg,                  
   @   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   F/tmp/pip-unpacked-wheel-7vhvci0g/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 || _ qq\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errnoZ
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   exportr   r   r   r   r   <module>   sF   
 k