
    >i-                        d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
Z
d dlmZ d dl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mZmZmZmZmZm Z  d dlm!Z" d dlm#Z#m$Z$m%Z%  ejL                  e'      Z( G d d      Z)y)    )annotationsN)suppress)TYPE_CHECKINGcast)ClientConnection)State)CommandsManagerEventsManager)CommandExecutionTimeoutWebSocketConnectionClosed)CDPEventResponse)get_browser_ws_address)AnyAsyncGenerator	AwaitableCallable	CoroutineOptionalUnion)connect)CommandT_CommandParamsT_CommandResponsec                  0   e Zd ZdZddeej                  df	 	 	 	 	 	 	 	 	 ddZed        Z	ed        Z
ddZ	 d	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 d dZd!d	Zd
 Zd Zd Zd Zd Zd Zd Zd"dZd#dZed$d       Zed%d       Zd&dZd'dZd Zd Zd Zd Z y)(ConnectionHandlerz
    WebSocket connection manager for Chrome DevTools Protocol endpoints.

    Handles connection lifecycle, command execution, and event subscription
    for both browser-level and page-level CDP endpoints.
    Nc           
     V   || _         || _        || _        || _        || _        d| _        t               | _        t               | _	        d| _
        t        j                  d       t        j                  d| j                    d| j                   dt        | j                                y)a  
        Initialize connection handler.

        Args:
            connection_port: Browser's debugging server port.
            page_id: Target page ID. If None, connects to browser-level endpoint.
            ws_address_resolver: Function to resolve WebSocket URL from port.
            ws_connector: WebSocket connection factory (mainly for testing).
            ws_address: WebSocket address. It has priority over connection_port and page_id.
        NzConnectionHandler initialized.zInit params: port=z
, page_id=z, ws_address_set=)_connection_port_page_id_ws_address_resolver_ws_connector_ws_address_ws_connectionr	   _command_managerr
   _events_handler_receive_taskloggerinfodebugbool)selfconnection_portpage_idws_address_resolverws_connector
ws_addresss         j/var/www/python/tenders/Scrapper/venv/lib/python3.12/site-packages/pydoll/connection/connection_handler.py__init__zConnectionHandler.__init__'   s    $ !0$7!)%:> / 1,5945 !6!6 7z$-- Q"4#3#3457	
    c                .    | j                   j                  S )z2Access captured network request and response logs.)r%   network_logsr+   s    r1   r5   zConnectionHandler.network_logsH   s     ##000r3   c                .    | j                   j                  S )z6Access currently active JavaScript dialog information.)r%   dialogr6   s    r1   r8   zConnectionHandler.dialogM   s     ##***r3   c                B  K   t        t              5  t        j                  d       | j	                          d{    t        t        | j                        j                          d{    t        j                  d       	 ddd       y7 S7 %# 1 sw Y   yxY ww)z6Test if WebSocket connection is active and responsive.zPinging WebSocket connectionNzPing OKTF)	r   	Exceptionr'   r)   _ensure_active_connectionr   r   r#   pingr6   s    r1   r<   zConnectionHandler.pingR   s}     i  	LL7800222')<)<=BBDDDLL#	 	2D	 s>   B)BB/B+B,B	BBBBBc           
       K   | j                          d{    | j                  j                  |      }t        j                  |      }	 t        t        | j                        }t        j                  d|j                  d       d|j                  d       d| d       t        j                         j                         }|j                  |       d{    t        j                  ||       d{   }t        j                         j                         |z
  }t        j                  d|j                  d       d	|d
d       t        j                   |      S 7 L7 7 o# t        j"                  $ rf | j                  j%                  |d          t        j'                  d|j                  d       d|j                  d       d| d       t)               t*        j,                  $ rK | j/                          d{  7   t        j1                  d|j                  d              t3               w xY ww)a  
        Send CDP command and await response.

        Args:
            command: CDP command to send.
            timeout: Maximum seconds to wait for response.

        Returns:
            Parsed response object matching command's expected type.

        Raises:
            CommandExecutionTimeout: If browser doesn't respond within timeout.
            WebSocketConnectionClosed: If connection closes during execution.
        NzSending command: id=idz	, method=methodz
, timeout=szCommand completed: id=z in z.3fzCommand timeout: id=z/WebSocket connection closed during command: id=)r;   r$   create_command_futurejsondumpsr   r   r#   r'   r)   getasyncioget_event_looptimesendwait_forloadsTimeoutErrorremove_pending_commanderrorr   
websocketsConnectionClosed_handle_connection_losswarningr   )	r+   commandtimeoutfuturecommand_strwsstartresponseelapseds	            r1   execute_commandz!ConnectionHandler.execute_command\   s    " ,,...&&<<WEjj)	.&(;(;<BLL&w{{4'8&97;;xCXBY Z")1& **,113E''+&&&")"2"267"CCH,,.335=GLL1'++d2C1DDQTUVWX::h'' 	/ 'C ## 	,!!88GLL&w{{4'8&97;;xCXBY Z")1& *++** 	...000NNLW[[Y]M^L_`a+--	.sZ   IE"4IBE) E%E) 7E'8A)E) !I%E) 'E) )BH>H	7H>>Ic                   K   | j                   j                  |||      }t        j                  d| d| d|        |S w)a  
        Register event listener for CDP events.

        Args:
            event_name: CDP event name (e.g., 'Page.loadEventFired').
            callback: Async function called when event occurs.
            temporary: If True, callback removed after first trigger.

        Returns:
            Callback ID for later removal.

        Note:
            Corresponding CDP domain must be enabled before events fire.
        zRegistered callback: id=z, event=z, temporary=)r%   register_callbackr'   r)   )r+   
event_namecallback	temporarycallback_ids        r1   r\   z#ConnectionHandler.register_callback   sO     ( **<<ZS\]&{m8J<|T]S^_	
 s   >A c                z   K   | j                   j                  |      }t        j                  d| d|        |S w)z'Remove registered event callback by ID.zRemoved callback: id=z
, removed=)r%   remove_callbackr'   r)   )r+   r`   removeds      r1   rb   z!ConnectionHandler.remove_callback   s;     &&66{C,[MG9MNs   9;c                j   K   t         j                  d       | j                  j                          yw)z&Remove all registered event callbacks.zClearing all callbacksN)r'   r)   r%   clear_callbacksr6   s    r1   re   z!ConnectionHandler.clear_callbacks   s%     -.,,.s   13c                R  K   | j                          d{    | j                  t        j                  d       yt	        t
        j                        5  | j                  j                          d{    ddd       t        j                  d       y7 7 $# 1 sw Y   #xY ww)z1Close WebSocket connection and release resources.Nz/Close called but no active WebSocket connectionzWebSocket connection closed.)	re   r#   r'   r)   r   rN   rO   closer(   r6   s    r1   rg   zConnectionHandler.close   s     ""$$$&LLJKj112 	.%%++---	.23 	% .	. 	.s9   B'B?B'B4B5B9B'BB$ B'c                   K   | j                   &| j                   j                  t        j                  u r.t        j                  d       | j                          d{    yy7 w)z@Ensure active connection exists, establishing new one if needed.Nz4No active WebSocket connection; establishing new one)r#   stater   CLOSEDr'   r)   _establish_new_connectionr6   s    r1   r;   z+ConnectionHandler._ensure_active_connection   sQ     &$*=*=*C*Cu||*SLLOP00222 +T2s   AA&A$A&c                .  K   | j                          d{   }t        j                  d|        | j                  |d       d{   | _        t        j                  | j                               | _        t        j                  d       y7 z7 Iw)z<Create fresh WebSocket connection and start event listening.NzConnecting to i   )max_sizez WebSocket connection established)
_resolve_ws_addressr'   r(   r!   r#   rE   create_task_receive_eventsr&   r)   )r+   r0   s     r1   rk   z+ConnectionHandler._establish_new_connection   s     3355
nZL12$($6$6% %7 %
 
 %001E1E1GH78 6
s"   BB2B	B
ABBc                f  K   | j                   r!t        j                  d       | j                   S | j                  s=| j	                  | j
                         d{   }t        j                  d|        |S d| j
                   d| j                   }t        j                  d|        |S 7 Tw)z5Determine correct WebSocket address based on page ID.z Using provided WebSocket addressNz*Resolved browser-level WebSocket address: zws://localhost:z/devtools/page/z'Resolved page-level WebSocket address: )r"   r'   r)   r   r    r   )r+   resolvedaddresss      r1   rn   z%ConnectionHandler._resolve_ws_address   s     LL;<###}}!66t7L7LMMHLLEhZPQO#D$9$9#:/$--Y>wiHI Ns   AB1B/AB1c                p  K   | j                   rH| j                   j                  t        j                  ur"| j                   j	                          d{    d| _         | j
                  r4| j
                  j                         s| j
                  j                          t        j                  d       y7 aw)z)Clean up resources after connection loss.NzConnection resources cleaned up)
r#   ri   r   rj   rg   r&   donecancelr'   r(   r6   s    r1   rP   z)ConnectionHandler._handle_connection_loss   s     4#6#6#<#<ELL#P%%++---"d&8&8&=&=&?%%'56 .s   AB6B4A"B6c                8  K   	 | j                         2 3 d{   }| j                  |       d{    #7 7 6 y# t        j                  $ r"}t        j                  d|        Y d}~yd}~wt        $ r}t        j                  d|         d}~ww xY ww)z:Main loop for receiving and processing WebSocket messages.NzConnection closed gracefully: z Unexpected error in event loop: )_incoming_messages_process_single_messagerN   rO   r'   r(   r:   rM   )r+   raw_messagees      r1   rp   z!ConnectionHandler._receive_events   s     	%)%<%<%> @ @k22;???@? &?** 	>KK8<== 	LL;A3?@	s[   B= ;7;= 9= ;= = BBA-(B-B9BBBc                  K   t        t        | j                        }|j                  t        j
                  ur9|j                          d{    |j                  t        j
                  ur8yy7 &w)z:Generator yielding raw messages from WebSocket connection.N)r   r   r#   ri   r   rj   recv)r+   rV   s     r1   rx   z$ConnectionHandler._incoming_messages   sL     "D$7$78hhell*	/! hhell*!s   A
A5A3#A51A5c                  K   | j                  |      }|sy| j                  |      r*t        t        |      }| j	                  |       d{    yt        t
        |      }| j                  |       d{    y7 /7 w)z%Process single raw WebSocket message.N)_parse_message_is_command_responser   r   _handle_command_messager   _handle_event_message)r+   rz   messages      r1   ry   z)ConnectionHandler._process_single_message   su     %%k2$$W-8W-G..w7778W-G,,W555 8 6s$   A
B A<)B 6A>7B >B c                    	 t        j                  |       S # t         j                  $ r t        j	                  d| dd  d       Y yw xY w)z*Parse raw message string into JSON object.zFailed to parse message: N   z...)rB   rJ   JSONDecodeErrorr'   rQ   )rz   s    r1   r   z ConnectionHandler._parse_message  sL    	::k**## 	NN6{4C7H6IMN	s    /A	A	c                L    d| v xr t        | j                  d      t              S )z?Determine if message is command response or event notification.r>   )
isinstancerD   int)r   s    r1   r   z&ConnectionHandler._is_command_response
  s#     wE:gkk$.?#EEr3   c                   K   t         j                  d|j                  d              | j                  j	                  |d   t        j                  |             yw)z"Process command response messages.zProcessing command response: r>   N)r'   r)   rD   r$   resolve_commandrB   rC   )r+   r   s     r1   r   z)ConnectionHandler._handle_command_message  sG     4W[[5F4GHI--gdmTZZ=PQs   AAc                   K   |j                  dd      }t        j                  d| d       | j                  j	                  |       d{    y7 w)z$Process event notification messages.r?   zunknown-eventzProcessing z eventN)rD   r'   r)   r%   process_event)r+   r   
event_types      r1   r   z'ConnectionHandler._handle_event_message  sE     [[?;
{:,f56""00999s   A
AAAc                "    d| j                    dS )z$String representation for debugging.ConnectionHandler(port=)r   r6   s    r1   __repr__zConnectionHandler.__repr__      ()>)>(?qAAr3   c                "    d| j                    dS )z$User-friendly string representation.r   r   r   r6   s    r1   __str__zConnectionHandler.__str__  r   r3   c                   K   | S w)zAsync context manager entry. r6   s    r1   
__aenter__zConnectionHandler.__aenter__"  s     s   c                @   K   | j                          d{    y7 w)z(Async context manager exit with cleanup.N)rg   )r+   exc_typeexc_valexc_tbs       r1   	__aexit__zConnectionHandler.__aexit__&  s     jjls   )
r,   zOptional[int]r-   Optional[str]r.   z)Callable[[int], Coroutine[Any, Any, str]]r/   ztype[Connect]r0   r   )returnr*   )<   )rR   z+Command[T_CommandParams, T_CommandResponse]rS   r   r   r   )F)r]   strr^   z!Callable[[dict], Awaitable[None]]r_   r*   r   r   )r`   r   r   r*   )r   z'AsyncGenerator[Union[str, bytes], None])rz   r   )rz   r   r   zUnion[CDPEvent, Response, None])r   zUnion[CDPEvent, Response]r   r*   )r   r   )r   r   )!__name__
__module____qualname____doc__r   rN   r   r2   propertyr5   r8   r<   rZ   r\   rb   re   rg   r;   rk   rn   rP   rp   rx   ry   staticmethodr   r   r   r   r   r   r   r   r   r3   r1   r   r      sT    *.!%I_&0&8&8$(
&
 
 G	

 $
 "
B 1 1 + + TV+.B+.MP+.	+.b  	 4 	
 
4/
	43	9	7	"6   F FR
:BBr3   r   )*
__future__r   rE   rB   logging
contextlibr   typingr   r   rN   websockets.asyncio.clientr   websockets.protocolr   pydoll.connection.managersr	   r
   pydoll.exceptionsr   r   pydoll.protocol.baser   r   pydoll.utilsr   r   r   r   r   r   r   r   r   Connectr   r   r   	getLoggerr   r'   r   r   r3   r1   <module>r      sc    "     &  6 % E 4 /[[[<PP			8	$I Ir3   