B
    ]t\t+                 @   sF  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yddlZW n ek
r   edY nX 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 G dd dejZ e  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.)rcParams)_Backend)Gcf   )backend_webagg_core)TimerTornadoc               @   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   Alib/python3.7/site-packages/matplotlib/backends/backend_webagg.pyrun+   s    zServerThread.runN)__name__
__module____qualname__r   r   r   r   r   r   *   s   r   c               @   s   e Zd Zdd Zdd ZdS )FigureCanvasWebAggc             C   s
   t   d S )N)show)r   r   r   r   r   3   s    zFigureCanvasWebAgg.showc             O   s
   t ||S )N)r
   )r   argskwargsr   r   r   	new_timer8   s    zFigureCanvasWebAgg.new_timerN)r   r   r   r   r   r   r   r   r   r   2   s   r   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 )WebAggApplicationFc               @   s   e Zd Zdd ZdS )zWebAggApplication.FavIconc             C   s.   |  dd ttd dd}| |  d S )NzContent-Typez	image/pngZdatapathZimageszmatplotlib.png)
set_headerr   r   writeZ
read_bytes)r   Z
image_pathr   r   r   getA   s    zWebAggApplication.FavIcon.getN)r   r   r   r    r   r   r   r   FavIcon@   s   r!   c                   s*   e Zd Zdd fdd
Zdd Z  ZS )z"WebAggApplication.SingleFigurePage )
url_prefixc               s   || _ t j||f| d S )N)r#   super__init__)r   applicationrequestr#   r   )	__class__r   r   r%   G   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 )Nzws://{req.host}{prefix}/)reqprefixzsingle_figure.html)r*   ws_urifig_id	toolitemscanvas)intr   get_fig_managerformatr'   r#   rendercoreNavigationToolbar2WebAggr-   r.   )r   fignummanagerr+   r   r   r   r    K   s    

z&WebAggApplication.SingleFigurePage.get)r   r   r   r%   r    __classcell__r   r   )r(   r   SingleFigurePageF   s   r8   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 )N)r#   r$   r%   )r   r&   r'   r#   r   )r(   r   r   r%   Z   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 )Nzws://{req.host}{prefix}/)r)   r*   zall_figures.html)r*   r+   Zfiguresr-   )r1   r'   r#   r2   sortedr   Zfigsitemsr3   r4   r-   )r   r+   r   r   r   r    ^   s    
z$WebAggApplication.AllFiguresPage.get)r   r   r   r%   r    r7   r   r   )r(   r   AllFiguresPageY   s   r;   c               @   s   e Zd Zdd ZdS )zWebAggApplication.MplJsc             C   s$   |  dd tj }| | d S )NzContent-Typezapplication/javascript)r   r3   FigureManagerWebAggZget_javascriptr   )r   Z
js_contentr   r   r   r    i   s    
zWebAggApplication.MplJs.getN)r   r   r   r    r   r   r   r   MplJsh   s   r=   c               @   s   e Zd Zdd ZdS )zWebAggApplication.Downloadc          	   C   sf   t |}t|}ddddddddd}| d	||d
 t }|jjj||d | 	|
  d S )Nzapplication/postscriptzapplication/pdfzimage/svg+xmlz	image/pngz
image/jpegz
image/tiffzapplication/emf)ZpsZepsZpdfZsvgZpngZjpegZtifZemfzContent-Typebinary)r1   )r/   r   r0   r   r    r   r.   figureZsavefigr   getvalue)r   r5   Zfmtr6   Z	mimetypesZbuffr   r   r   r    q   s    
zWebAggApplication.Download.getN)r   r   r   r    r   r   r   r   Downloadp   s   rA   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)r/   r5   r   r0   r6   Zadd_web_sockethasattrrB   )r   r5   r   r   r   open   s
    

z WebAggApplication.WebSocket.openc             C   s   | j |  d S )N)r6   Zremove_web_socket)r   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loadsrG   r   r0   r5   Zhandle_json)r   messager6   r   r   r   
on_message   s    
z&WebAggApplication.WebSocket.on_messagec             C   s   |  t| d S )N)write_messagerI   dumps)r   Z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)r>   zdata:image/png;base64,{0}base64
r"   )rG   rM   r1   encodereplace)r   ZblobZdata_urir   r   r   send_binary   s
    z'WebAggApplication.WebSocket.send_binaryN)	r   r   r   rG   rD   rE   rL   rO   rT   r   r   r   r   	WebSocket   s   rU   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 | 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/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StaticFileHandlerr3   r<   get_static_file_pathr!   r8   r;   r=   rU   rA   )r   r#   )r(   r   r   r%      s"    

zWebAggApplication.__init__Nc             C   s   | j r
d S | |d}|| _dd }|d kr6td | _n|| _td | _xn|| jtd D ]R}y||| j W n2 tjk
r } z|jtj	kr W d d }~X Y qXX || _P qXW t
dd| _ d S )	N)r#   c             s   sV   x t td|D ]}| | V  qW x.t |d D ]}| td| d|  V  q0W 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randomZrandint)port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   addressrb   ZlistensocketerrorerrnoZ
EADDRINUSE
SystemExit)clsr#   rb   rg   Zappre   er   r   r   
initialize   s(    

zWebAggApplication.initializec          	      sl    j r
d S tjj  fddtfdd}d _ td tj	  |  
  W d Q R X d S )Nc                  s$      td tj  d _d S )NzServer is stoppedF)stopprintsysstdoutflushstartedr   )rl   r   r   r   shutdown  s    
z)WebAggApplication.start.<locals>.shutdownc           
   3   s8   t  t j fdd} z
d V  W d t  t j|  X d S )Nc                s
     S )N)Zadd_callback_from_signal)Zsigframe)r   ru   r   r   <lambda>  s    z?WebAggApplication.start.<locals>.catch_sigint.<locals>.<lambda>)signalSIGINT)Zold_handler)r   ru   r   r   catch_sigint  s    
z-WebAggApplication.start.<locals>.catch_sigintTz"Press Ctrl+C to stop WebAgg server)rt   r   r   r   r   r   rp   rq   rr   rs   r   )rl   rz   r   )rl   r   ru   r   r      s    	
zWebAggApplication.start)r"   )r"   NN)r   r   r   rf   rt   r   rZ   ZRequestHandlerr!   r8   r;   r=   rA   Z	websocketZWebSocketHandlerrU   r%   classmethodrn   r   r7   r   r   )r(   r   r   <   s   '#,r   c             C   sj   dd l }t  t s t  | 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*   r,   r-   r.   rb   zutf-8)Ztornado.templater   rn   webagg_server_threadZis_aliver   Znumberr   r3   r<   r[   Z	read_texttemplateZTemplateZgenerater#   r4   r-   r.   rb   decode)r?   r   r5   Ztpltr   r   r   ipython_inline_display%  s    

r   c               @   s.   e Zd ZeZejZedd Z	edd Z
dS )_BackendWebAggc             C   s   | j   d S )N)r.   Z	draw_idle)r6   r   r   r   trigger_manager_draw=  s    z#_BackendWebAgg.trigger_manager_drawc              C   sP   t   djt jt jd} td r6dd l}||  ntd|  t 	  d S )Nzhttp://127.0.0.1:{port}{prefix})rb   r*   zwebagg.open_in_browserr   zTo view figure, visit {0})
r   rn   r1   rb   r#   r   
webbrowserrD   rp   r   )Zurlr   r   r   r   r   A  s    
z_BackendWebAgg.showN)r   r   r   r   ZFigureCanvasr3   r<   ZFigureManagerstaticmethodr   r   r   r   r   r   r   8  s   r   )*__doc__
contextlibr   rj   ior   rI   osZpathlibr   ra   rq   rx   rh   Z	threadingr   ImportErrorRuntimeErrorZtornado.webZtornado.ioloopZtornado.websocketZ
matplotlibr   Zmatplotlib.backend_basesr   Zmatplotlib._pylab_helpersr   r"   r	   r3   r
   ZThreadr   r|   ZFigureCanvasWebAggCorer   rZ   ZApplicationr   r   Zexportr   r   r   r   r   <module>   s>   
 j