
    CCfT'                        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Zd dlm	Z	m
Z
mZmZmZmZmZmZ d dlmZmZmZmZ  G d de      Z G d d	      Zdd
Zy)    )annotationsN)Enum)AnyCallableDictListLiteralTupleUnionNoReturn)WebSocketStateMessage	WebSocketWebSocketDisconnectc                      e Zd ZdZdZdZy)ReceiveTypetextbytesjsonN)__name__
__module____qualname__TEXTBYTESJSON     T/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/websocket_rooms/room.pyr   r      s    DEDr   r   c                     e Zd ZU eej
                  j                  ej                  j                  ej                  j                  f   Z	de
d<   de
d<   de
d<   de
d<   de
d	<   d
e
d<   d ZddZddZddZddZddZd ZddZd d!dZd"dZej
                  j                  f	 	 	 d#dZ	 d$	 	 	 d%dZ	 d$	 	 	 d%dZd&dZy)'RoomzList[WebSocket]_websocketszCDict[Literal['before', 'after'], Callable[[Room, WebSocket], None]]_on_connectzNDict[Literal['text', 'bytes', 'json'], Callable[[Room, WebSocket, Any], None]]_on_receive_on_disconnectzasyncio.Queue_to_pushzasyncio.Task_publisher_taskc                |    g | _         i | _        i | _        i | _        t	        j
                         | _        d | _        y N)r!   r#   r$   r"   asyncioQueuer%   r&   selfs    r   __init__zRoom.__init__%   s7     #r   c                  K   | j                   s(t        j                  | j                               | _         | j                  j                  d      }|rt         || |             d{    |j                          d{    | j                  j                  |       | j                  j                  d      }|rt         || |             d{    | j                  |       d{    y7 7 r7 "7 w)a  
        Accepts a websocket connection and, adds it to the room clients list, and runs the 
        _run_client_lifecycle function to manage the connection.

        Parameters
        ----------
        websocket : WebSocket
            The websocket to connect

        Returns
        -------
        NoReturn
            The function runs for the entire client lifetime.
        beforeNafter)r&   r)   create_task
_publisherr"   getawait_if_awaitableacceptr!   append_run_client_lifecycle)r,   	websocketr/   r0   s       r   connectzRoom.connect-   s      ###*#6#6t7H#ID !!%%h/$VD)%<===   	*  $$W-$U4%;<<<((333 >  =3sI   A'C:)C2*C:C4AC:C6C:,C8-C:4C:6C:8C:c                p   K   | j                   r$| j                  j                  |       d{    yy7 w)z
        Pushes the message object into the message queue.

        Parameters
        ----------
        message_object : Tuple[Any, Literal["text", "bytes", "json"]]
            the message object to be pushed
        N)r&   r%   put)r,   message_objects     r   _pushz
Room._pushH   s1      --##N333  3s   +646c                F   K   | j                  |df       d{    y7 w)z
        Pushes the json data as a broadcast to all the room clients

        Parameters
        ----------
        message : dict
            the message to be pushed
        r   Nr=   r,   messages     r   	push_jsonzRoom.push_jsonT         jj'6*+++   !!c                F   K   | j                  |df       d{    y7 w)z
        Pushes the str data as a broadcast to all the room clients

        Parameters
        ----------
        message: str
            the message to be pushed
        r   Nr?   r@   s     r   	push_textzRoom.push_text_   rC   rD   c                F   K   | j                  |df       d{    y7 w)z
        Pushes the bytes data as a broadcast to all the room clients

        Parameters
        ----------
        message: bytes
            the message to be pushed
        r   Nr?   r@   s     r   
push_byteszRoom.push_bytesj   s      jj'7+,,,rD   c                  K   	 | j                   j                          d{   \  }}g }t        | j                        dkD  rg| j                  j	                         }	  |j                  d|       |       d{    |j                  |       t        | j                        dkD  rg|| _        7 7 8# t        $ r Y w xY ww)z
        A publisher that runs on the message queue and pushes the message to all the clients.
        This courtine is ran in the background in the _publisher_task task.
        Nr   send_)r%   r3   lenr!   pop__getattribute__r   r6   )r,   rA   message_typeliving_connectionsr8   s        r   r2   zRoom._publisheru   s     
 ,0MM,=,=,?&?#Wl24d&&'!+ ,,002	L)44u\N5KLWUUU #)))4 d&&'!+  2D &?
 V* sK   CB2;CB6 ;B4<B6  )C*	C4B6 6	C?CCCc                  K   	 	 |j                   t        j                  k7  rt        d      |j	                          d{   }t        j                  |       |j                  |       d}d}t        j                  j                  |j                         v r|t        j                  j                     }t        j                  j                  | j                  j                         v r)| j                  t        j                  j                     }nt        j                  | j                  j                         v r`t        j                  |j!                  d            }| j                  t        j                  j                     }nt        j"                  j                  |j                         v r|t        j"                  j                     }t        j"                  j                  | j                  j                         v r(| j                  t        j"                  j                     }npt        j                  j                  | j                  j                         v r<t        j                  |      }| j                  t        j                  j                     }|r+|r) || ||      }t%        j&                  |      r
| d{    7 7 	# t(        $ r | j+                  |d       d{  7   Y yw xY ww)z
        Manages the clients lifecycle, calling on_receive callback when a message is received from the websocket.

        Raises
        ------
        RuntimeError('WebSocket is not connected. Need to call "accept" first.')
        Tz8WebSocket is not connected. Need to call "accept" first.Nzutf-8)closed)application_stater   	CONNECTEDRuntimeErrorreceivelogginginfo_raise_on_disconnectr   r   valuekeysr#   r   r   loadsdecoder   inspectisawaitabler   remove)r,   r8   rA   funcr   func_ress         r   r7   zRoom._run_client_lifecycle   s@    "	6...2J2JJ&R  *3):):)<#<W%..w7$$**glln<";#4#4#:#:;D"((..$2B2B2G2G2II#//0A0A0G0GH$))T-=-=-B-B-DD#zz$++g*>?#//0@0@0F0FG %%++w||~=";#3#3#9#9:D"''--1A1A1F1F1HH#//0@0@0F0FG$))//43C3C3H3H3JJ#zz$/#//0@0@0F0FGD#D)T:H**84&= 
 $=2 '" 	6++i+555	6sM   K=<K  KJK KK K K:1K42K:7K=9K::K=c                  K   | j                   j                  d      }|t         || |             d{    |s|j                          d{    | j                  j                  |       | j                  g k(  r!| j                  j                          d| _        | j                   j                  d      }|t         || |             d{    yy7 7 7 
w)zA
        Remove a websocket from the room, and close it.
        r/   Nr0   )r$   r3   r4   closer!   r_   r&   cancel)r,   r8   rQ   r/   r0   s        r   r_   zRoom.remove   s      $$((2$VD)%<===//###	*r!  '')#'D ##''0$U4%;<<<  ># =s4   3CCCCBCCCCCc                   K   | j                   j                         }|D ]  }| j                  |       d{     y7 w)z9
        Close the room and all its connections.
        N)r!   copyr_   )r,   
websocketsr8   s      r   rc   z
Room.close   s@      %%**,
# 	)I++i(((	)(s   4A >A c                6     dvrt        d      d fd}|S )a  
        The decorator to specify the callbacks that will be run when a message is received from client websocket.

        Parameters
        ----------
        mode : Literal["text", "bytes", "json"]
            The type of the message that callback will be ran on.

        Raises
        ------
        RuntimeError('The "mode" argument should be "text", "bytes" or "json".')

        Returns
        -------
        Callable[[Room, WebSocket, Any], None]
            The function that the decorator receives.

        )r   r   r   z8The "mode" argument should be "text", "bytes" or "json".c                &    | j                   <   | S r(   )r#   r`   moder,   s    r   innerzRoom.on_receive.<locals>.inner       %)DT"Kr   )r`   &Callable[[Room, WebSocket, Any], None]rT   r,   rk   rl   s   `` r   
on_receivezRoom.on_receive   s*    * 00J 	 r   c                6     dvrt        d      d fd}|S )a  
        The decorator to specify the callbacks that will run on websockets connection.

        Parameters
        ----------
        mode : Literal["before", "after"]
            The execution time of the callback - before / after connecting the websocket.

        Raises
        ------
        RuntimeError('The "mode" argument should be "before" or "after".')

        Returns
        -------
        Callable[[Room, WebSocket], None]
            The function that the decorator receives.
        r/   r0   2The "mode" argument should be "before" or "after".c                &    | j                   <   | S r(   )r"   rj   s    r   rl   zRoom.on_connect.<locals>.inner  rm   r   r`   !Callable[[Room, WebSocket], None]ro   rp   s   `` r   
on_connectzRoom.on_connect   &    ( **STT	 r   c                6     dvrt        d      d fd}|S )a  
        The decorator to specify the callbacks that will run on websockets disconnect.

        Paramaters
        ----------
        mode : Literal["before", "after"]
            The execution time of the callback - before / after disconnecting the websocket.

        Raises
        ------
        RuntimeError('The "mode" argument should be "before" or "after".')

        Returns
        -------
        Callable[[Room, WebSocket], None]
            The function that the decorator receives.
        rs   rt   c                &    | j                   <   | S r(   )r$   rj   s    r   rl   z!Room.on_disconnect.<locals>.inner   s    (,D%Kr   rv   ro   rp   s   `` r   on_disconnectzRoom.on_disconnect	  ry   r   c                    | S r(   r   r+   s    r   __call__zRoom.__call__&  s    r   N)r8   r   returnr   )r<   z,Tuple[Any, Literal['text', 'bytes', 'json']])rA   dictr   None)rA   strr   r   )rA   r   r   r   )F)r8   r   rQ   boolr   r   )r   r   )rk   zRoom.RECEIVE_TYPESr   rn   )r0   )rk   zLiteral['before', 'after']r   rw   )r   r    )r   r   r   r   r   r   rY   r   r   RECEIVE_TYPES__annotations__r-   r9   r=   rB   rF   rH   r2   r7   r_   rc   rq   rx   r|   r~   r   r   r   r    r       s     0 0 6 68I8I8O8OOM ! TT__WW!!$46
4	,	,	-2"*6X=$) *5)9)9)?)?&	/B 29.	*< 29.	*:r   r    c                P   K   t        j                  |       r|  d {    y y 7 wr(   )r]   r^   )ra   s    r   r4   r4   *  s#     8$ %s   &$&)ra   r   )
__future__r   r)   enumr   r]   r   rV   typingr   r   r   r   r	   r
   r   r   starlette.websocketsr   r   r   r   r   r    r4   r   r   r   <module>r      sM    "     	 	 	 Y X$ M M`r   