o
    衡iO%                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlmZm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mZ d dl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dS )    N)ABCabstractmethod)Mapping)IOBase)PIPE)sleep)IOAny)request)URLError)WebDriverException)utilsc                   @   s"  e Zd ZdZ					d'dedB dedeeB ee B dB deeef dB dedB d	dfd
dZ	e
d	efddZed	ee fddZe
d	efddZejded	dfddZd(ddZd(ddZd	efddZd(ddZd(ddZd(ddZd(d d!Zd"ed	dfd#d$Zd	edB fd%d&ZdS ))Servicea  Abstract base class for all service objects that manage driver processes.

    Services typically launch a child program in a new process as an interim process to
    communicate with a browser.

    Args:
        executable_path: (Optional) Install path of the executable.
        port: (Optional) Port for the service to run on, defaults to 0 where the operating system will decide.
        log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
        env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
        driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
    Nr   executable_pathport
log_outputenvdriver_path_env_keyreturnc                 K   s   |  t |trt|ddd| _n|tjkrd | _n|d u s"|tjkr'tj| _n|| _|p/t | _	|
di | _| j
dd| _|pDtj| _|| _|  pN|| _d S )Nza+zutf-8)encodingpopen_kwcreation_flagsr   )
isinstancestropenr   
subprocessSTDOUTDEVNULLr   	free_portr   popr   r   osenvironr   DRIVER_PATH_ENV_KEYenv_path_path)selfr   r   r   r   r   kwargs r'   r/var/www/html/asbeauty/laura_geller_scraping/env/lib/python3.10/site-packages/selenium/webdriver/common/service.py__init__4   s   	


zService.__init__c                 C   s   dt d| j S )zGets the url of the Service.zhttp://	localhost)r   join_host_portr   r%   r'   r'   r(   service_urlO   s   zService.service_urlc                 C   s   t d)z7A List of program arguments (excluding the executable).z2This method needs to be implemented in a sub class)NotImplementedErrorr,   r'   r'   r(   command_line_argsT   s   zService.command_line_argsc                 C   s
   | j pdS )N )r$   r,   r'   r'   r(   pathY   s   
zService.pathvaluec                 C   s   t || _d S N)r   r$   )r%   r2   r'   r'   r(   r1   ]   s   c                 C   sp   | j du r	td| | j  d}	 |   |  rdS ttdd|  d |d7 }|d	kr7td
| j  q)zStarts the Service.

        Raises:
            WebDriverException: Raised either when it can't start the service
                or when it can't connect to the service
        NService path cannot be None.r   Tg{Gz?g?g      ?   F   zCan not connect to the Service )r$   r   _start_processassert_process_still_runningis_connectabler   min)r%   countr'   r'   r(   starta   s   
zService.startc                 C   s(   | j  }|rtd| j d| dS )z1Check if the underlying process is still running.zService z' unexpectedly exited. Status code was: N)processpollr   r$   )r%   return_coder'   r'   r(   r8   w   s   
z$Service.assert_process_still_runningc                 C   s   t | jS )a"  Check if the service is ready via the W3C WebDriver /status endpoint.

        This makes an HTTP request to the /status endpoint and verifies if it is ready to accept new sessions.

        Returns:
            True if the service is ready to accept new sessions, False otherwise.
        )r   is_url_connectabler   r,   r'   r'   r(   r9   }   s   zService.is_connectablec                 C   sT   zt | j d W n
 ty   Y dS w tdD ]}|  s# dS td qdS )zFDispatch an HTTP request to the shutdown endpoint to stop the service.z	/shutdownN   r5   )r
   urlopenr-   r   ranger9   r   )r%   _r'   r'   r(   send_remote_shutdown_command   s   
z$Service.send_remote_shutdown_commandc                 C   s   | j ttjhvr t| j tr| j   nt| j tr t| j  | j	durP| j	
 du rRzz|   W n	 ty<   Y nw W |   dS W |   dS |   w dS dS )zStops the service.N)r   r   r   r   r   r   closeintr    r=   r>   rE   	TypeError_terminate_processr,   r'   r'   r(   stop   s    zService.stopc              	   C   s   zM| j j| j j| j j}}}|||fD ]}z|  W q ty%   Y qw | j   z
| j d W W dS  tj	yM   t
jddd | j   Y W dS w  ty^   t
jddd Y dS w )a#  Terminate the child process.

        On POSIX this attempts a graceful SIGTERM followed by a SIGKILL,
        on a Windows OS kill is an alias to terminate.  Terminating does
        not raise itself if something has gone wrong but (currently)
        silently ignores errors here.
        <   zTService process refused to terminate gracefully with SIGTERM, escalating to SIGKILL.T)exc_infoz"Error terminating service process.N)r=   stdinstdoutstderrrF   AttributeError	terminatewaitr   TimeoutExpiredloggererrorkillOSError)r%   rM   rN   rO   streamr'   r'   r(   rI      s0   

zService._terminate_processc                 C   s$   z|    W d S  ty   Y d S w r3   )rJ   	Exceptionr,   r'   r'   r(   __del__   s
   zService.__del__r1   c              
   C   s  |g}| |   | jdtjdk}z>d}tjdkr+t }tjtj	B |_
tj|_tj|f| j|| j| jt| j|d| j| _td| j| jj| j| j W dS  tyZ     ty } z|jtjkr~| jdu rptdtdtj| j d| d}~ww )	zyCreates a subprocess by executing the command provided.

        Args:
            path: full command to execute
        	close_fdswin32N)r   r[   rN   rO   rM   creationflagsstartupinfozNStarted executable: `%s` in a child process with pid: %s using %s to output %sr4   'z(' executable may have wrong permissions.)extendr/   r   r   sysplatformr   STARTUPINFOCREATE_NEW_CONSOLESTARTF_USESHOWWINDOWdwFlagsSW_HIDEwShowWindowPopenr   r   r   r   r=   rT   debugr$   pidrH   rW   errnoEACCESr   r    r1   basename)r%   r1   cmdclose_file_descriptors
start_infoerrr'   r'   r(   r7      sV   
	

zService._start_processc                 C   s   | j r
t| j d S d S r3   )r"   r    getenvr,   r'   r'   r(   r#      s   zService.env_path)Nr   NNN)r   N)__name__
__module____qualname____doc__r   rG   r   r	   r   r)   propertyr-   r   listr/   r1   setterr<   r8   boolr9   rE   rJ   rI   rZ   r7   r#   r'   r'   r'   r(   r   &   sJ    







-r   )rl   loggingr    r   ra   abcr   r   collections.abcr   ior   r   timer   typingr   r	   urllibr
   urllib.errorr   selenium.common.exceptionsr   selenium.webdriver.commonr   	getLoggerrt   rT   r   r'   r'   r'   r(   <module>   s"   
