U
    ^»{j A  ã                   @  s@  d 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mZ ddlm	Z	 ddl
Z
ddlmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZ ddlmZmZ ddlmZmZ ddlmZ e	�rddlm Z  ddl!m"Z" ddlm#Z#m$Z$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+ e
 ,e-¡Z.G dd„ deƒZ/G dd„ deƒZ0dS )z)Provides the async api: `Browser`, `Tab`.é    )ÚannotationsN)ÚLock)ÚTYPE_CHECKING)Úprotocolé   )ÚBroker)ÚBrowserClosedErrorÚBrowserDepsErrorÚBrowserFailedErrorÚChromium)ÚChannelClosedErrorÚPipe)ÚSessionÚTarget)ÚTmpDirWarningÚ_manual_thread_pool)Úkill)ÚPath)ÚTracebackType)ÚAnyÚ	GeneratorÚMutableMapping)ÚSelf)ÚBrowserImplInterface)ÚChannelInterfacec                   @  s   e Zd ZdZddœdd„ZdS )ÚTabz<A wrapper for `Target`, so user can use `Tab`, not `Target`.ÚNone©Úreturnc                 Ã  s   | j jj| jd�I dH  dS )zClose the tab.)Ú	target_idN)Ú_brokerZ_browserÚ	close_tabr   ©Úself© r$   úZ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/choreographer/browser_async.pyÚclose)   s    z	Tab.closeN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   r$   r$   r$   r%   r   &   s   r   c                      sˆ  e Zd ZU dZded< ded< ded< dZd	ed
< ddœdd„Zddœdd„Zddœdd„ZdQe	e
dœddddddœdd„Zddœdd„Zddœ‡ fdd„Zd dœd!d"„Zd#dœd$d%„ZdRd'dd(œd)d*„Zddœd+d,„Zddœd-d.„Zd/d0d1d2d3œd4d5„Zddœd6d7„Zd8dd9œd:d;„Zd<dd=œd>d?„Zd@dœdAdB„ZddœdCdD„ZdEdœdFdG„ZdSdIdJœd<d'd'dd8dKœdLdM„Zd<dNd=œdOdP„Z‡  ZS )TÚBrowserz3`Browser` is the async implementation of `Browser`.ú/subprocess.Popen[bytes] | subprocess.Popen[str]Ú
subprocesszMutableMapping[str, Tab]ÚtabszMutableMapping[str, Target]ÚtargetsNzasyncio.Task[Any] | NoneÚ_watch_dog_taskr   r   c                 C  s   t ƒ | _d S ©N)r   Ú
_open_lockr"   r$   r$   r%   Ú
_make_lock;   s    zBrowser._make_lockÚboolc                 Ã  s"   | j  ¡ rdS | j  ¡ I d H  dS ©NTF)r2   ÚlockedÚacquirer"   r$   r$   r%   Ú_is_open>   s    
zBrowser._is_openc                 C  s@   z$| j  ¡ r| j  ¡  W dS W dS W n tk
r:   Y dS X d S r5   )r2   r6   ÚreleaseÚRuntimeErrorr"   r$   r$   r%   Ú_release_lockG   s    


zBrowser._release_lock)Úbrowser_clsÚchannel_clszstr | Path | Noneztype[BrowserImplInterface]ztype[ChannelInterface]r   )Úpathr<   r=   Úkwargsr   c                K  sZ   t  d¡ tjddd�| _|  ¡  i | _i | _|ƒ | _t	| | jƒ| _
|| j|f|Ž| _dS )a”  
        Construct a new browser instance.

        Args:
            path: The path to the browser executable.
            browser_cls: The type of browser (default: `Chromium`).
            channel_cls: The type of channel to browser (default: `Pipe`).
            kwargs: The arguments that the browser_cls takes. For example,
                headless=True/False, enable_gpu=True/False, etc.

        zAttempting to open new browser.é   Zchecking_close©Úmax_workersÚnameN)Ú_loggerÚdebugr   ÚManualThreadExecutorÚ_process_executorr3   r.   r/   Ú_channelr   r    Ú_browser_impl)r#   r>   r<   r=   r?   r$   r$   r%   Ú__init__Q   s    
þzBrowser.__init__c                 C  s
   | j  ¡ S )zReturn if process is isolated.)rI   Úis_isolatedr"   r$   r$   r%   rK   s   s    zBrowser.is_isolatedc              
   ƒ  s„  t  d¡ ˆ  ¡ I dH r tdƒ‚tˆ jdƒr6ˆ jj}nd}tjd|d�\ˆ _	}ddœ‡ fd	d
„}t  
d¡ t ¡ }| ˆ j|¡I dH ˆ _tƒ  dˆ j¡ ˆ  tdˆ jƒ¡ znt  
d¡ t ˆ  ¡ ¡ˆ _t  
d¡ ˆ j ¡  t  
d¡ ˆ j ¡  t  
d¡ t d¡I dH  ˆ  ¡ I dH  W nf tttjfk
�r~ } z>tˆ jdƒ�rRˆ jj �rRt!|‚tddddˆ jj"› d�ƒ|‚W 5 d}~X Y nX dS )zOpen the browser.zOpening browser.NzCan't re-open the browserÚlogger_parserZbrowser_proc)Úparserr,   r   c                    sF   ˆ j  ¡  ˆ j  ¡ } ˆ j}ˆ j  ¡ }ˆ j  ¡ }tj| f||dœ|—ŽS )N)ÚstderrÚenv)rI   Zpre_openZget_cliÚ_logger_pipeZget_envZget_popen_argsr-   ÚPopen)ÚclirN   rO   Úargsr"   r$   r%   Úrun‡   s    



ÿýüzBrowser.open.<locals>.runzTrying to open browser.Ú0Ú zStarting watchdogzOpening channel.zRunning read loopzPopulating Targetsr   Úmissing_libsz7The browser seemed to close immediately after starting.z@You can set the `logging.Logger` level lower to see more output.zAYou may try installing a known working copy of Chrome by running z†`$ choreo_get_chrome`.It may be your browser auto-updated and will now work upon restart. The browser we tried to start is located at Ú.)#rD   Úinfor8   r:   ÚhasattrrI   rL   ÚlogistroZgetPipeLoggerrP   rE   ÚasyncioÚget_running_loopÚrun_in_executorrG   r-   ÚsuperrJ   r    Ú_add_sessionr   Zcreate_taskÚ	_watchdogr0   rH   ÚopenZrun_read_loopÚsleepÚpopulate_targetsr   r
   ÚCancelledErrorrW   r	   r>   )r#   rM   Ú_rT   ÚloopÚe©Ú	__class__r"   r%   rb   w   sV    

þ
þ






ÿþü	÷zBrowser.openr   c                 Ã  s   |   ¡ I dH  | S )z=Open browser as context to launch on entry and close on exit.N)rb   r"   r$   r$   r%   Ú
__aenter__¹   s    zBrowser.__aenter__zGenerator[Any, Any, Browser]c                 C  s   |   ¡  ¡ S )z?If you await the `Browser()`, it will implicitly call `open()`.)rk   Ú	__await__r"   r$   r$   r%   rl   ¿   s    zBrowser.__await__r   z
int | None)Úwaitr   c                 Ã  s„   t | dƒsdS |dkr*| j ¡ d k}| S z&t ¡ }| | j| jj|¡I d H  W n. tjk
rh   Y dS  tj	k
r~   Y dS X dS )Nr-   Tr   F)
rZ   r-   Úpollr\   r]   r^   rG   rm   ÚTimeoutExpiredre   )r#   rm   r8   rg   r$   r$   r%   Ú
_is_closedÃ   s"    
ýzBrowser._is_closedc              	   Ã  s  |   ¡ I d H rt d¡ d S zt d¡ |  d¡I d H  W n^ ttfk
r^   t d¡ Y d S  tk
rz   t d¡ Y n  tjk
r˜   t d¡ Y nX | j	 
¡  | j dd�I d H rºd S |   ¡ I d H rÖt d	¡ d S t d
¡ t| jƒ | j dd�I d H �rd S tdƒ‚d S )NzNo _close(), already is closedzTrying Browser.closeúBrowser.closez.Browser is closed trying to send Browser.closez)Can't send Browser.close on close channelz3Close was cancelled, _broker must be shutting down.r@   )rm   z'Browser is closed after closing channelz"Resorting to unclean kill browser.é   z)Couldn't close or kill browser subprocess)rp   rD   rE   Úsend_commandr   r
   r   r\   re   rH   r&   Úwarningr   r-   r:   r"   r$   r$   r%   Ú_closeÛ   s0    






zBrowser._closec                 Ã  sØ   t  d¡ | jr$t  d¡ | j ¡  |  ¡ s0dS z&t  d¡ |  ¡ I dH  t  d¡ W n tk
rj   Y nX | j 	¡  t  d¡ | j
rœt | j
¡ t  d¡ | j ¡  t  d¡ | j 	¡  t  d	¡ | jjd
dd� dS )úClose the browser.zClosing browser.zCancelling watchdog.NzStarting browser close methods.zBrowser close methods finished.zBroker cleaned up.zLogging pipe closed.zBrowser channel closed.z"Browser implementation cleaned up.FT©rm   Zcancel_futures)rD   rY   r0   rE   Úcancelr;   ru   ÚProcessLookupErrorr    ÚcleanrP   Úosr&   rH   rI   rG   Úshutdownr"   r$   r$   r%   r&   û   s,    










rq   ztype[BaseException] | NonezBaseException | NonezTracebackType | Nonezbool | None)Útype_ÚvalueÚ	tracebackr   c                 Ã  s   |   ¡ I dH  dS )rv   N)r&   )r#   r}   r~   r   r$   r$   r%   Ú	__aexit__  s    zBrowser.__aexit__c              
   Ã  sæ   t jddd�}z¸zœt ¡ �Š tjdtd	� t d
¡ t	 
¡ }t d¡ | || jj¡I d H  t d¡ d | _|  ¡ I d H  t	 d¡I d H  | || jj¡I d H  W 5 Q R X W n t	jk
rÂ   Y nX W 5 |jddd� t d¡ X d S )Nr   Zwatchdog_waitrA   FTrw   z$Watchdog full shutdown (in finally:)Úignore)ÚcategoryzIn watchdogzRunning wait.z2Wait expired, Browser is being closed by watchdog.)r   rF   r|   rD   rE   ÚwarningsÚcatch_warningsÚfilterwarningsr   r\   r]   Zdebug2r^   r-   rm   rt   r0   r&   rc   rI   rz   re   )r#   Z	_executorrg   r$   r$   r%   ra   "  s6    þ


þ

ÿþ
zBrowser._watchdogr   )Útabr   c                 C  s*   t |tƒstd| j› �ƒ‚|| j|j< d S )Nztab must be an object of )Ú
isinstancer   Ú	TypeErrorZ	_tab_typer.   r   )r#   r†   r$   r$   r%   Ú_add_tabB  s    
zBrowser._add_tabÚstr)r   r   c                 C  s   t |tƒr|j}| j|= d S r1   )r‡   r   r   r.   )r#   r   r$   r$   r%   Ú_remove_tabG  s    
zBrowser._remove_tabz
Tab | Nonec                 C  s    | j  ¡ rtt| j  ¡ ƒƒS dS )zz
        Get the first tab if there is one. Useful for default tabs.

        Returns:
            A tab object.

        N)r.   ÚvaluesÚnextÚiterr"   r$   r$   r%   Úget_tabL  s    
zBrowser.get_tabc                 Ã  s  |   ¡ I dH rtdƒ‚|  d¡I dH }d|kr@tdƒt|d ƒ‚|d d D ]²}|d d	krL|d
 | jkrL|d
 }t|| jƒ}z| ¡ I dH  W nP t	j
k
rà } z0|jt	jjkrÎt d|› d�¡ W Y ¢
qLn‚ W 5 d}~X Y nX |  |¡ t d|› d�¡ qLdS )zHSolicit the actual browser for all targets to add to the browser object.Nz-populate_targets() called on a closed browserzTarget.getTargetsÚerrorzCould not get targetsÚresultZtargetInfosÚtypeÚpageÚtargetIdzTarget z# not found (could be closed before)zThe target z
 was added)rp   r   rs   r:   Ú	Exceptionr.   r   r    Úcreate_sessionr   ÚDevtoolsProtocolErrorÚcodeZEcodeZTARGET_NOT_FOUNDrD   rt   r‰   rE   )r#   ÚresponseZjson_responser   Únew_tabrh   r$   r$   r%   rd   X  s2    ÿ
ÿþ
ÿ

zBrowser.populate_targetsr   c                 Ã  sr   |   ¡ I dH rtdƒ‚t dtj¡ |  d¡I dH }d|krLtdƒt |¡‚|d d }t	|| j
ƒ}|  |¡ |S )	z‰
        Create a browser session. Only in supported browsers, is experimental.

        Returns:
            A session object.

        Nz+create_session() called on a closed browserz_Creating new sessions on Browser() only works with some versions of Chrome, it is experimental.zTarget.attachToBrowserTargetr�   zCould not create sessionr‘   Z	sessionId)rp   r   rƒ   Úwarnr   ZExperimentalFeatureWarningrs   r:   r—   r   r    r`   )r#   r™   Z
session_idZnew_sessionr$   r$   r%   r–   v  s&    ýÿÿþ
zBrowser.create_sessionrV   F)Úwindow)ÚurlÚwidthÚheightrœ   r   c          	      Ã  s¢   |   ¡ I dH rtdƒ‚d|i}|r*||d< |r6||d< |rBd|d< | jd|d	�I dH }d
|krntdƒt |¡‚|d d }t|| jƒ}|  |¡ | 	¡ I dH  |S )aE  
        Create a new tab.

        Args:
            url: the url to navigate to, default ""
            width: the width of the tab (headless only)
            height: the height of the tab (headless only)
            window: default False, if true, create new window, not tab

        Returns:
            a tab.

        Nz(create_tab() called on a closed browser.r�   rž   rŸ   TZ	newWindowzTarget.createTarget)Úparamsr�   zCould not create tabr‘   r”   )
rp   r   rs   r:   r   r—   r   r    r‰   r–   )	r#   r�   rž   rŸ   rœ   r    r™   r   rš   r$   r$   r%   Ú
create_tab‘  s.    ÿÿþ
zBrowser.create_tabzprotocol.BrowserResponsec                 Ã  sd   |   ¡ I dH rtdƒ‚t|tƒr&|j}| jdd|id�I dH }|  |¡ d|kr`tdƒt 	|¡‚|S )zq
        Close a tab by its id.

        Args:
            target_id: the targetId of the tab to close.

        Nz&close_tab() called on a closed browserzTarget.closeTargetr”   )Úcommandr    r�   zCould not close tab)
rp   r   r‡   r   r   rs   r‹   r:   r   r—   )r#   r   r™   r$   r$   r%   r!   ½  s$    
þ
ÿÿþzBrowser.close_tab)N)r   )rV   NN)r'   r(   r)   r*   Ú__annotations__r0   r3   r8   r;   r   r   rJ   rK   rb   rk   rl   rp   ru   r&   r€   ra   r‰   r‹   r�   rd   r–   r¡   r!   Ú__classcell__r$   r$   ri   r%   r+   .   sD   
	 þû"B 
    üú,r+   )1r*   Ú
__future__r   r\   r{   r-   rƒ   r   Útypingr   r[   Zchoreographerr   Z_brokersr   Zbrowsersr   r	   r
   r   Zchannelsr   r   Zprotocol.devtools_asyncr   r   Úutilsr   r   Zutils._killr   Úpathlibr   Útypesr   r   r   r   Útyping_extensionsr   Zbrowsers._interface_typer   Zchannels._interface_typer   Ú	getLoggerr'   rD   r   r+   r$   r$   r$   r%   Ú<module>   s2   
