o
    /h                     @   s   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m	Z	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mZmZ d dlmZmZmZ d	efd
dZG dd dZdS )    N)defaultdict)wraps)AnyDefaultDictDictList)Channel)NotConnectedError)HEARTBEAT_PAYLOADPHOENIX_CHANNELChannelEventsMessage)CallbackT_ParamSpecT_Retvalfuncc                    s*   t  dtjdtjdtf fdd}|S )Nargskwargsreturnc                     s"   | d j s
t j | i |S )Nr   )	connectedr	   __name__)r   r   r    L/var/www/html/govbot/env/lib/python3.10/site-packages/realtime/connection.pywrapper   s   

z"ensure_connection.<locals>.wrapper)r   r   r   r   r   )r   r   r   r   r   ensure_connection   s    r   c                   @   s   e Zd Zdi dfdededeeef deddf
d	d
Ze	dddZ
dddZdddZdddZe	dddZdddZdddZe	dedefddZdddZdS )SocketF   urlauto_reconnectparamshb_intervalr   Nc                 C   s@   || _ tt| _d| _|| _|| _|  d| _|| _tt| _dS )a  
        `Socket` is the abstraction for an actual socket connection that receives and 'reroutes' `Message` according to its `topic` and `event`.
        Socket-Channel has a 1-many relationship.
        Socket-Topic has a 1-many relationship.
        :param url: Websocket URL of the Realtime server. starts with `ws://` or `wss://`
        :param params: Optional parameters for connection.
        :param hb_interval: WS connection is kept alive by sending a heartbeat message. Optional, defaults to 5.
        FN)	r   r   listchannelsr   r    r!   
kept_aliver   )selfr   r   r    r!   r   r   r   __init__    s   
zSocket.__init__c                 C   s&   t  }|t |  |   dS )z
        Wrapper for async def _listen() to expose a non-async interface
        In most cases, this should be the last method executed as it starts an infinite listening loop.
        :return: None
        N)asyncioget_event_looprun_until_completegather_listen_keep_aliver%   loopr   r   r   listen:   s   zSocket.listenc                    s   	 z;| j  I dH }tdi t|}|jtjkrW q| j	|j
g D ]}|jD ]}|jd|jfv r:||j q*q%W n9 tjjyv   | jrltd |  I dH  | j D ]\}}|D ]	}| I dH  q`qZntd Y dS Y nw q)zN
        An infinite loop that keeps listening.
        :return: None
        TN*5Connection with server closed, trying to reconnect..."Connection with the server closed.r   )ws_connectionrecvr   jsonloadseventr   replyr#   gettopic	listenerscallbackpayload
websockets
exceptionsConnectionClosedr   logginginfo_connectitems_join	exception)r%   msgchannelclr:   r#   r   r   r   r+   D   s<   

zSocket._listenc                 C       t  }||   d| _dS )zR
        Wrapper for async def _connect() to expose a non-async interface
        TN)r'   r(   r)   rC   r   r-   r   r   r   connectb   s   
zSocket.connectc                    s<   t | jI d H }|jrtd || _d| _d S td)NzConnection was successfulTzConnection Failed)	r>   rK   r   openrA   rB   r3   r   	Exception)r%   r3   r   r   r   rC   j   s   

zSocket._connectc                 C   rJ   )zP
        Wrapper for async def _close() to expose a non-async interface
        FN)r'   r(   r)   _closer   r-   r   r   r   closet   s   
zSocket.closec                    s   | j  I d H  d S )N)r3   rO   )r%   r   r   r   rN   }   s   zSocket._closec                    s   	 z t ttjtdd}| jt|I dH  t	
| jI dH  W n# tjjyE   | jr;td |  I dH  ntd Y dS Y nw q)zx
        Sending heartbeat to server every 5 seconds
        Ping - pong messages to verify connection is alive
        TN)r:   r7   r=   refr1   r2   )dictr   r   	heartbeatr
   r3   sendr5   dumpsr'   sleepr!   r>   r?   r@   r   rA   rB   rC   rF   )r%   datar   r   r   r,      s,   
zSocket._keep_aliver:   c                 C   s"   t | || j}| j| | |S )z
        :param topic: Initializes a channel and creates a two-way association with the socket
        :return: Channel
        )r   r    r#   append)r%   r:   chanr   r   r   set_channel   s   zSocket.set_channelc                 C   sD   | j  D ]\}}|D ]}td| ddd |jD  d qqdS )zd
        Prints a list of topics and event the socket is listening to
        :return: None
        zTopic: z | Events: c                 S   s   g | ]\}}|qS r   r   ).0e_r   r   r   
<listcomp>   s    z"Socket.summary.<locals>.<listcomp>]N)r#   rD   print	callbacks)r%   r:   chansrX   r   r   r   summary   s
   $zSocket.summary)r   N)r   
__module____qualname__strboolr   r   intr&   r   r/   r+   rK   rC   rO   rN   r,   r   rY   rb   r   r   r   r   r      s6    


	





r   )r'   r5   rA   collectionsr   	functoolsr   typingr   r   r   r   r>   realtime.channelr   realtime.exceptionsr	   realtime.messager
   r   r   r   realtime.typesr   r   r   r   r   r   r   r   r   <module>   s    