o
    i/+                  
   @   sH  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yK Z zededZ[ww 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 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.)_Backend)Gcf   )backend_webagg_core)TimerTornadoc                   @      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   ]/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/matplotlib/backends/backend_webagg.pyrun+      zServerThread.runN)__name__
__module____qualname__r   r   r   r   r   r   *       r   c                   @   s   e Zd ZeZdd ZdS )FigureCanvasWebAggc                 C   s
   t   d S r   )showr   r   r   r   r   5   s   
zFigureCanvasWebAgg.showN)r   r   r   r	   
_timer_clsr   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                   @   r
   )zWebAggApplication.FavIconc                 C   s(   |  dd | tt d  d S )NContent-Typez	image/pngzimages/matplotlib.png)
set_headerwriter   mplget_data_path
read_bytesr   r   r   r   get@   s   zWebAggApplication.FavIcon.getNr   r   r   r&   r   r   r   r   FavIcon?   r   r(   c                       *   e Zd Zdd fdd
Zdd Z  ZS )z"WebAggApplication.SingleFigurePage 
url_prefixc                       || _ t j||fi | d S r   r,   super__init__r   applicationrequestr,   kwargs	__class__r   r   r0   F      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}/reqprefixzsingle_figure.html)r;   ws_urifig_id	toolitemscanvas)intr   get_fig_managerformatr3   r,   rendercoreNavigationToolbar2WebAggr>   r?   )r   fignummanagerr<   r   r   r   r&   J   s   

z&WebAggApplication.SingleFigurePage.getr   r   r   r0   r&   __classcell__r   r   r5   r   SingleFigurePageE       rJ   c                       r)   )z WebAggApplication.AllFiguresPager*   r+   c                   r-   r   r.   r1   r5   r   r   r0   Y   r7   z)WebAggApplication.AllFiguresPage.__init__c                 C   s:   dj | j| jd}| jd| j|ttj tj	j
d d S )Nr8   r9   zall_figures.html)r;   r<   figuresr>   )rB   r3   r,   rC   sortedr   figsitemsrD   rE   r>   )r   r<   r   r   r   r&   ]   s   
z$WebAggApplication.AllFiguresPage.getrH   r   r   r5   r   AllFiguresPageX   rK   rP   c                   @   r
   )zWebAggApplication.MplJsc                 C   s$   |  dd tj }| | d S )Nr    zapplication/javascript)r!   rD   FigureManagerWebAggget_javascriptr"   )r   
js_contentr   r   r   r&   h   s   
zWebAggApplication.MplJs.getNr'   r   r   r   r   MplJsg   r   rT   c                   @   r
   )zWebAggApplication.Downloadc                 C   sR   t |}t|}| dtj|d t }|jj	j
||d | |  d S )Nr    binary)rB   )r@   r   rA   r!   	mimetypes	types_mapr&   r   r?   figuresavefigr"   getvalue)r   rF   fmtrG   buffr   r   r   r&   p   s   
zWebAggApplication.Download.getNr'   r   r   r   r   Downloado   r   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r| d d S d S )Nset_nodelayT)r@   rF   r   rA   rG   add_web_sockethasattrr^   )r   rF   r   r   r   open|   s   

z WebAggApplication.WebSocket.openc                 C   s   | j |  d S r   )rG   remove_web_socketr   r   r   r   on_close   s   z$WebAggApplication.WebSocket.on_closec                 C   sJ   t |}|d dkr|d | _d S t| j}|d ur#|| d S d S )Ntypesupports_binaryvalue)jsonloadsre   r   rA   rF   handle_json)r   messagerG   r   r   r   
on_message   s   
z&WebAggApplication.WebSocket.on_messagec                 C   s   |  t| d S r   )write_messagerg   dumps)r   contentr   r   r   	send_json   r   z%WebAggApplication.WebSocket.send_jsonc                 C   s>   | j r| j|dd d S d|ddd}| | d S )NT)rU   zdata:image/png;base64,{0}base64
r*   )re   rl   rB   encodereplace)r   blobdata_urir   r   r   send_binary   s   z'WebAggApplication.WebSocket.send_binaryN)	r   r   r   re   ra   rc   rk   ro   rv   r   r   r   r   	WebSockety   s    rw   r*   c              
      s   |r|d dkr|d dksJ 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/(.*)imagesz/favicon.icoz	/([0-9]+)r,   z/?z
/js/mpl.jsz/([0-9]+)/wsz/([0-9]+)/download.([a-z0-9.]+))template_path)r/   r0   r   webStaticFileHandlerrD   rQ   get_static_file_pathr   r#   r$   r(   rJ   rP   rT   rw   r]   )r   r,   r5   r   r   r0      s8   

 
zWebAggApplication.__init__Nc                 C   s   | j rd S | |d}|| _dd }|d u rtjd | _n|| _tjd | _|| jtjd D ]*}z	||| j W n tjyS } z|j	t	j
krI W Y d }~q.d }~ww || _ ntdd| _ d S )	Nr+   c                 s   sP    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)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#   rcParamsaddressr   listensocketerrorerrno
EADDRINUSE
SystemExit)clsr,   r   r   appr   er   r   r   
initialize   s4   

zWebAggApplication.initializec                    s    j rd S 	 tjj  fddtfdd}d _ td tj	  |  
  W d    d S 1 s;w   Y  d S )Nc                      s$      td tj  d _d S )NzServer is stoppedF)stopprintsysstdoutflushstartedr   )r   r   r   r   shutdown  s   

z)WebAggApplication.start.<locals>.shutdownc               
   3   sF    t  t j fdd} zd V  W t  t j|  d S t  t j|  w )Nc                    s
     S r   )add_callback_from_signal)sigframer   r   r   r   <lambda>  s   
 z?WebAggApplication.start.<locals>.catch_sigint.<locals>.<lambda>)signalSIGINT)old_handlerr   r   r   catch_sigint
  s   "z-WebAggApplication.start.<locals>.catch_sigintTz"Press Ctrl+C to stop WebAgg server)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   r}   RequestHandlerr(   rJ   rP   rT   r]   	websocketWebSocketHandlerrw   r0   classmethodr   r   rI   r   r   r5   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?   r   zutf-8)tornado.templater   r   webagg_server_threadis_aliver   numberr   rD   rQ   r   	read_texttemplateTemplategenerater,   rE   r>   r?   r   decode)rX   r   rF   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 r   )r?   	draw_idle)rG   r   r   r   trigger_manager_draw5  s   z#_BackendWebAgg.trigger_manager_drawc                  C   sd   t   djt jt jt jd} tjd r%dd l}|	| s$t
d|  nt
d|  t   d S )Nzhttp://{address}:{port}{prefix})r   r   r;   zwebagg.open_in_browserr   zTo view figure, visit {0})r   r   rB   r   r   r,   r#   r   
webbrowserra   r   r   )urlr   r   r   r   r   9  s   

z_BackendWebAgg.showN)r   r   r   r   FigureCanvasrD   rQ   FigureManagerstaticmethodr   r   r   r   r   r   r   0  s    
r   )+__doc__
contextlibr   r   ior   rg   rV   pathlibr   r   r   r   r   	threadingr   ImportErrorerrRuntimeErrortornado.webtornado.iolooptornado.websocket
matplotlibr#   matplotlib.backend_basesr   matplotlib._pylab_helpersr   r*   r   rD   r	   Threadr   r   FigureCanvasWebAggCorer   r}   Applicationr   r   exportr   r   r   r   r   <module>   sD    
	 c