§
    §Mºf±.  ã                   óð   — d dl Z 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 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  G d	„ d
¦  «        Z G d„ d¦  «        Z G d„ de¦  «        Zefd„Z e¦   «         ZdS )é    N)Údeepcopy)Úsettings)Úsetting_changed)Úimport_string)ÚDEFAULT_CHANNEL_LAYERé   )ÚChannelFullÚInvalidChannelLayerErrorc                   óX   — e Zd ZdZd„ Zd„ Zed„ ¦   «         Zd„ Zd„ Z	d„ Z
d„ Zd	„ Zd
„ ZdS )ÚChannelLayerManagerzR
    Takes a settings dictionary of backends and initialises them on request.
    c                 óF   — i | _         t          j        | j        ¦  «         d S ©N)Úbackendsr   ÚconnectÚ_reset_backends©Úselfs    úN/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/channels/layers.pyÚ__init__zChannelLayerManager.__init__   s#   € ØˆŒÝÔ Ô 4Ñ5Ô5Ð5Ð5Ð5ó    c                 ó$   — |dk    r	i | _         dS dS )zX
        Removes cached channel layers when the CHANNEL_LAYERS setting changes.
        ÚCHANNEL_LAYERSN)r   )r   ÚsettingÚkwargss      r   r   z#ChannelLayerManager._reset_backends   s#   € ð Ð&Ò&Ð&ØˆDŒMˆMˆMð 'Ð&r   c                 ó.   — t          t          di ¦  «        S )Nr   )Úgetattrr   r   s    r   ÚconfigszChannelLayerManager.configs"   s   € õ •xÐ!1°2Ñ6Ô6Ð6r   c                 óp   — | j         |                              di ¦  «        }|                      ||¦  «        S )z,
        Instantiate channel layer.
        ÚCONFIG)r   ÚgetÚ_make_backend©r   ÚnameÚconfigs      r   Úmake_backendz ChannelLayerManager.make_backend'   s6   € ð ”˜dÔ#×'Ò'¨°"Ñ5Ô5ˆØ×!Ò! $¨Ñ/Ô/Ð/r   c                 ó˜   — 	 | j         |         d         }n # t          $ r t          d|z  ¦  «        ‚w xY w|                      ||¦  «        S )zB
        Instantiate channel layer using its test config.
        ÚTEST_CONFIGzNo TEST_CONFIG specified for %s)r   ÚKeyErrorr
   r!   r"   s      r   Úmake_test_backendz%ChannelLayerManager.make_test_backend.   sd   € ð	UØ”\ $Ô'¨Ô6ˆFˆFøÝð 	Uð 	Uð 	UÝ*Ð+LÈtÑ+SÑTÔTÐTð	Uøøøà×!Ò! $¨Ñ/Ô/Ð/s   ‚ –3c                 ó6  — d| j         |         v rt          d|z  ¦  «        ‚	 t          | j         |         d         ¦  «        }nO# t          $ r t          d|z  ¦  «        ‚t          $ r' t          d| j         |         d         ›d|›�¦  «        ‚w xY w |di |¤ŽS )NÚROUTINGzBROUTING key found for %s - this is no longer needed in Channels 2.ÚBACKENDzNo BACKEND specified for %szCannot import BACKEND z specified for © )r   r
   r   r(   ÚImportError)r   r#   r$   Úbackend_classs       r   r!   z!ChannelLayerManager._make_backend8   sà   € à˜œ TÔ*Ð*Ð*Ý*ØTØññô ð ð
	Ý)¨$¬,°tÔ*<¸YÔ*GÑHÔHˆMˆMøÝð 	Qð 	Qð 	QÝ*Ð+HÈ4Ñ+OÑPÔPÐPÝð 	ð 	ð 	Ý*Ð*à”< Ô% iÔ0Ð0Ð0°$°$ð8ñô ð ð	øøøð ˆ}Ð&Ð&˜vÐ&Ð&Ð&s   £ A ÁABc                 óh   — || j         vr|                      |¦  «        | j         |<   | j         |         S r   )r   r%   ©r   Úkeys     r   Ú__getitem__zChannelLayerManager.__getitem__L   s6   € Ø�d”mÐ#Ð#Ø!%×!2Ò!2°3Ñ!7Ô!7ˆDŒM˜#ÑØŒ}˜SÔ!Ð!r   c                 ó   — || j         v S r   )r   r1   s     r   Ú__contains__z ChannelLayerManager.__contains__Q   s   € Ø�d”lÐ"Ð"r   c                 óP   — | j                              |d¦  «        }|| j         |<   |S )z»
        Sets an alias to point to a new ChannelLayerWrapper instance, and
        returns the old one that it replaced. Useful for swapping out the
        backend during tests.
        N)r   r    )r   r2   ÚlayerÚolds       r   ÚsetzChannelLayerManager.setT   s,   € ð Œm×Ò  TÑ*Ô*ˆØ"ˆŒ�cÑØˆ
r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Úpropertyr   r%   r)   r!   r3   r5   r9   r-   r   r   r   r      s±   € € € € € ðð ð6ð 6ð 6ðð ð ð ð7ð 7ñ „Xð7ð0ð 0ð 0ð0ð 0ð 0ð'ð 'ð 'ð("ð "ð "ð
#ð #ð #ðð ð ð ð r   r   c                   óÈ   — e Zd ZdZdZdd„Zd„ Zd„ Zd„ Z e	j
        d	¦  «        Z e	j
        d
¦  «        Zdd                     e¦  «        z   dz   dz   Zdd„Zd„ Zdd„Zd„ ZdS )ÚBaseChannelLayerzf
    Base channel layer class that others can inherit from, with useful
    common functionality.
    éd   é<   Nc                 ó4   — || _         || _        |pi | _        d S r   ©ÚexpiryÚcapacityÚchannel_capacity)r   rE   rF   rG   s       r   r   zBaseChannelLayer.__init__g   s#   € ØˆŒØ ˆŒØ 0Ð 6°BˆÔÐÐr   c                 ó  — g }|                      ¦   «         D ]h\  }}t          |d¦  «        r|                     ||f¦  «         Œ-|                     t          j        t          j        |¦  «        ¦  «        |f¦  «         Œi|S )z 
        Takes an input channel_capacity dict and returns the compiled list
        of regexes that get_capacity will look for as self.channel_capacity
        Úmatch)ÚitemsÚhasattrÚappendÚreÚcompileÚfnmatchÚ	translate)r   rG   ÚresultÚpatternÚvalues        r   Úcompile_capacitiesz#BaseChannelLayer.compile_capacitiesl   s�   € ð
 ˆØ.×4Ò4Ñ6Ô6ð 	Oð 	O‰NˆG�Uõ �w Ñ(Ô(ð OØ—’˜w¨Ð.Ñ/Ô/Ð/Ð/à—’�rœz­'Ô*;¸GÑ*DÔ*DÑEÔEÀuÐMÑNÔNÐNÐNØˆr   c                 ó\   — | j         D ]\  }}|                     |¦  «        r|c S Œ| j        S )a  
        Gets the correct capacity for the given channel; either the default,
        or a matching result from channel_capacity. Returns the first matching
        result; if you want to control the order of matches, use an ordered dict
        as input.
        )rG   rI   rF   )r   ÚchannelrR   rF   s       r   Úget_capacityzBaseChannelLayer.get_capacity{   sE   € ð "&Ô!6ð 	 ð 	 ÑˆG�XØ�}Š}˜WÑ%Ô%ð  Ø���ð àŒ}Ðr   c                 ód   — t          |t          ¦  «        rt          |¦  «        | j        k     rdS dS )NTF)Ú
isinstanceÚstrÚlenÚMAX_NAME_LENGTH©r   r#   s     r   Úmatch_type_and_lengthz&BaseChannelLayer.match_type_and_length‡   s1   € Ý�d�CÑ Ô ð 	¥c¨$¡i¤i°$Ô2FÒ&FÐ&FØ�4Øˆur   z!^[a-zA-Z\d\-_.]+(\![\d\w\-_.]*)?$z^[a-zA-Z\d\-_.]+$z'{} name must be a valid unicode string zwith length < {} zGcontaining only ASCII alphanumerics, hyphens, underscores, or periods, znot {}Fc                 ó"  — |                       |¦  «        rSt          | j                             |¦  «        ¦  «        r,d|v r&|                     d¦  «        s|rt          d¦  «        ‚dS t          | j                             d|¦  «        ¦  «        ‚)Nú!z5Specific channel names in receive() must end at the !TÚChannel)r^   ÚboolÚchannel_name_regexrI   ÚendswithÚ	TypeErrorÚinvalid_name_errorÚformat)r   r#   Úreceives      r   Úvalid_channel_namez#BaseChannelLayer.valid_channel_name—   s“   € Ø×%Ò% dÑ+Ô+ð 	Ý�DÔ+×1Ò1°$Ñ7Ô7Ñ8Ô8ð à˜$�;�; t§}¢}°SÑ'9Ô'9�;¸g�;Ý#ØOñô ð ð �tÝ˜Ô/×6Ò6°yÀ$ÑGÔGÑHÔHÐHr   c                 óÎ   — |                       |¦  «        r)t          | j                             |¦  «        ¦  «        rdS t	          | j                             d|¦  «        ¦  «        ‚)NTÚGroup)r^   rb   Úgroup_name_regexrI   re   rf   rg   r]   s     r   Úvalid_group_namez!BaseChannelLayer.valid_group_name¢   s_   € Ø×%Ò% dÑ+Ô+ð 	Ý�DÔ)×/Ò/°Ñ5Ô5Ñ6Ô6ð Ø�tÝ˜Ô/×6Ò6°wÀÑEÔEÑFÔFÐFr   c                 ó˜   ‡ ‡— |rdnd}t          |t          ¦  «        }|r|s
J d¦   «         ‚t          ˆˆ fd„|D ¦   «         ¦  «        sJ ‚dS )NTFznames must be a non-empty listc              3   óF   •K  — | ]}‰                      |‰¬ ¦  «        V — ŒdS ))rh   N)ri   )Ú.0rV   rh   r   s     €€r   ú	<genexpr>z7BaseChannelLayer.valid_channel_names.<locals>.<genexpr>­   sG   øè è € ð 
ð 
ØBIˆD×#Ò# G°WÐ#Ñ=Ô=ð
ð 
ð 
ð 
ð 
ð 
r   )rY   ÚlistÚall)r   Únamesrh   Ú_non_empty_listÚ_names_types   ` `  r   Úvalid_channel_namesz$BaseChannelLayer.valid_channel_names¨   s‰   øø€ Ø"'Ð2˜$˜$¨UˆÝ  ­Ñ-Ô-ˆØÐP ;ÐPÐPÐ0PÑPÔPÐPåð 
ð 
ð 
ð 
ð 
ØMRð
ñ 
ô 
ñ 
ô 
ð 	
ð 	
ð 	
ð ˆtr   c                 óN   — d|v r |d|                      d¦  «        dz   …         S |S )zõ
        Given a channel name, returns the "non-local" part. If the channel name
        is a process-specific channel (contains !) this means the part up to
        and including the !; if it is anything else, this means the full name.
        r`   Nr   )Úfindr]   s     r   Únon_local_namezBaseChannelLayer.non_local_name²   s2   € ð �$ˆ;ˆ;ØÐ,˜$Ÿ)š) C™.œ.¨1Ñ,Ð,Ô-Ð-àˆKr   )rB   rA   N)F)r:   r;   r<   r=   r\   r   rT   rW   r^   rM   rN   rc   rl   rg   rf   ri   rm   rw   rz   r-   r   r   r@   r@   _   s  € € € € € ðð ð
 €Oð7ð 7ð 7ð 7ð
ð ð ð
ð 
ð 
ðð ð ð $˜œÐ$HÑIÔIÐØ!�r”zÐ"6Ñ7Ô7Ðà1Ø
×
$Ò
$ _Ñ
5Ô
5ñ	6à
Sñ	Tð ñ	ð ð	Ið 	Ið 	Ið 	IðGð Gð Gðð ð ð ð	ð 	ð 	ð 	ð 	r   r@   c                   ór   ‡ — e Zd ZdZ	 	 	 	 dˆ fd„	ZddgZd	„ Zd
„ Zdd„Zd„ Z	d„ Z
d„ Zd„ Zd„ Zd„ Zd„ Zˆ xZS )ÚInMemoryChannelLayerz0
    In-memory channel layer implementation
    rB   é€Q rA   Nc                 ól   •—  t          ¦   «         j        d|||dœ|¤Ž i | _        i | _        || _        d S )NrD   r-   )Úsuperr   ÚchannelsÚgroupsÚgroup_expiry)r   rE   r‚   rF   rG   r   Ú	__class__s         €r   r   zInMemoryChannelLayer.__init__Ã   s[   ø€ ð 	�‰ŒÔð 	
ØØØ-ð	
ð 	
ð ð		
ð 	
ð 	
ð ˆŒØˆŒØ(ˆÔÐÐr   r�   Úflushc              ƒ   óÈ  K  — t          |t          ¦  «        s
J d¦   «         ‚|                      |¦  «        s
J d¦   «         ‚d|vsJ ‚| j                             |t          j        ¦   «         ¦  «        }|                     ¦   «         | j        k    rt          |¦  «        ‚| 
                    t          j        ¦   «         | j        z   t          |¦  «        f¦  «        ƒ d{V —† dS )zF
        Send a message onto a (general or specific) channel.
        zmessage is not a dictúChannel name not validÚ__asgi_channel__N)rY   Údictri   r€   Ú
setdefaultÚasyncioÚQueueÚqsizerF   r	   ÚputÚtimerE   r   )r   rV   ÚmessageÚqueues       r   ÚsendzInMemoryChannelLayer.sendÙ   sã   è è € õ
 ˜'¥4Ñ(Ô(ÐAÐAÐ*AÑAÔAÐAØ×&Ò& wÑ/Ô/ÐIÐIÐ1IÑIÔIÐIð "¨Ð0Ð0Ð0Ð0à”×(Ò(¨µ'´-±/´/ÑBÔBˆà�;Š;‰=Œ=˜DœMÒ)Ð)Ý˜gÑ&Ô&Ð&ð �iŠi�œ™œ t¤{Ñ2µH¸WÑ4EÔ4EÐFÑGÔGÐGÐGÐGÐGÐGÐGÐGÐGÐGr   c              ƒ   óp  K  — |                       |¦  «        sJ ‚|                      ¦   «          | j                             |t	          j        ¦   «         ¦  «        }	 |                     ¦   «         ƒ d{V —†\  }}|                     ¦   «         r| j        |= n!# |                     ¦   «         r| j        |= w xY w|S )zÊ
        Receive the first message that arrives on the channel.
        If more than one coroutine waits on the same channel, a random one
        of the waiting coroutines will get the result.
        N)ri   Ú_clean_expiredr€   r‰   rŠ   r‹   r    Úempty)r   rV   r�   Ú_r�   s        r   rh   zInMemoryChannelLayer.receiveì   sÂ   è è € ð ×&Ò& wÑ/Ô/Ð/Ð/Ð/Ø×ÒÑÔÐà”×(Ò(¨µ'´-±/´/ÑBÔBˆð	+Ø$Ÿyšy™{œ{Ð*Ð*Ð*Ð*Ð*Ð*‰JˆAˆwà�{Š{‰}Œ}ð +Ø”M 'Ð*øøð �{Š{‰}Œ}ð +Ø”M 'Ð*Ð*Ð*Ð*Ð*àˆs   ÁB ÂB3ú	specific.c              ƒ   óh   K  — |›dd                      d„ t          d¦  «        D ¦   «         ¦  «        ›�S )zx
        Returns a new channel name that can be used by something in our
        process as a specific channel.
        z
.inmemory!Ú c              3   óR   K  — | ]"}t          j        t          j        ¦  «        V — Œ#d S r   )ÚrandomÚchoiceÚstringÚascii_letters)rp   Úis     r   rq   z3InMemoryChannelLayer.new_channel.<locals>.<genexpr>  s/   è è € ÐKÐK¸A•F”M¥&Ô"6Ñ7Ô7ÐKÐKÐKÐKÐKÐKr   é   )ÚjoinÚrange)r   Úprefixs     r   Únew_channelz InMemoryChannelLayer.new_channel   s@   è è € ð ˆFˆFØ�GŠGÐKÐKÅÀrÁÄÐKÑKÔKÑKÔKÐKð
ð 	
r   c                 ó4  — t          | j                             ¦   «         ¦  «        D ]Â\  }}|                     ¦   «         s©|j        d         d         t          j        ¦   «         k     r�|                     ¦   «          |                      |¦  «         |                     ¦   «         r| j        |= |                     ¦   «         s(|j        d         d         t          j        ¦   «         k     °�ŒÃt          t          j        ¦   «         ¦  «        | j	        z
  }| j
        D ]~}t          | j
                             |t          ¦   «         ¦  «        ¦  «        D ]G}| j
        |         |         r2t          | j
        |         |         ¦  «        |k     r| j
        |         |= ŒHŒdS )z¢
        Goes through all messages and groups and removes those that are expired.
        Any channel with an expired message is removed from all groups.
        r   N)rr   r€   rJ   r”   Ú_queuerŽ   Ú
get_nowaitÚ_remove_from_groupsÚintr‚   r�   r    r9   )r   rV   r�   ÚtimeoutÚgroups        r   r“   z#InMemoryChannelLayer._clean_expired  su  € õ # 4¤=×#6Ò#6Ñ#8Ô#8Ñ9Ô9ð 	/ð 	/‰NˆG�Uà—k’k‘m”mð /¨¬°Q¬¸Ô(:½T¼Y¹[¼[Ò(HÐ(HØ× Ò Ñ"Ô"Ð"à×(Ò(¨Ñ1Ô1Ð1à—;’;‘=”=ð /Øœ gÐ.ð —k’k‘m”mð /¨¬°Q¬¸Ô(:½T¼Y¹[¼[Ò(HÐ(Høõ •d”i‘k”kÑ"Ô" TÔ%6Ñ6ˆØ”[ð 	4ð 	4ˆEÝ ¤§¢°µs±u´uÑ =Ô =Ñ>Ô>ð 4ð 4�ð ”K Ô& wÔ/ð4å˜DœK¨Ô.¨wÔ7Ñ8Ô8¸7ÒBÐBð œ EÔ*¨7Ð3øð4ð	4ð 	4r   c              ƒ   ó&   K  — i | _         i | _        d S r   )r€   r�   r   s    r   r„   zInMemoryChannelLayer.flush*  s   è è € ØˆŒØˆŒˆˆr   c              ƒ   ó
   K  — d S r   r-   r   s    r   ÚclosezInMemoryChannelLayer.close.  s   è è € àˆr   c                 óL   — | j                              ¦   «         D ]	}||v r||= Œ
dS )zW
        Removes a channel from all groups. Used when a message on it expires.
        N)r�   Úvalues)r   rV   r€   s      r   r§   z(InMemoryChannelLayer._remove_from_groups2  s?   € ð œ×*Ò*Ñ,Ô,ð 	&ð 	&ˆHØ˜(Ð"Ð"Ø˜WÐ%øð	&ð 	&r   c              ƒ   óþ   K  — |                       |¦  «        s
J d¦   «         ‚|                      |¦  «        s
J d¦   «         ‚| j                             |i ¦  «         t	          j        ¦   «         | j        |         |<   dS )z3
        Adds the channel name to a group.
        zGroup name not validr†   N)rm   ri   r�   r‰   rŽ   ©r   rª   rV   s      r   Ú	group_addzInMemoryChannelLayer.group_add<  sƒ   è è € ð
 ×$Ò$ UÑ+Ô+ÐCÐCÐ-CÑCÔCÐCØ×&Ò& wÑ/Ô/ÐIÐIÐ1IÑIÔIÐIàŒ×Ò˜u bÑ)Ô)Ð)Ý&*¤i¡k¤kˆŒ�EÔ˜7Ñ#Ð#Ð#r   c              ƒ   ó  K  — |                       |¦  «        s
J d¦   «         ‚|                      |¦  «        s
J d¦   «         ‚|| j        v r4|| j        |         v r| j        |         |= | j        |         s| j        |= d S d S d S )NzInvalid channel nameúInvalid group name)ri   rm   r�   r±   s      r   Úgroup_discardz"InMemoryChannelLayer.group_discardG  s«   è è € à×&Ò& wÑ/Ô/ÐGÐGÐ1GÑGÔGÐGØ×$Ò$ UÑ+Ô+ÐAÐAÐ-AÑAÔAÐAà�D”KÐÐØ˜$œ+ eÔ,Ð,Ð,Ø”K Ô& wÐ/Ø”;˜uÔ%ð 'Ø”K Ð&Ð&Ð&ð	  Ðð'ð 'r   c              ƒ   ó\  K  — t          |t          ¦  «        s
J d¦   «         ‚|                      |¦  «        s
J d¦   «         ‚|                      ¦   «          | j                             |t          ¦   «         ¦  «        D ]/}	 |                      ||¦  «        ƒ d {V —† Œ # t          $ r Y Œ,w xY wd S )NzMessage is not a dictr´   )	rY   rˆ   rm   r“   r�   r    r9   r‘   r	   )r   rª   r�   rV   s       r   Ú
group_sendzInMemoryChannelLayer.group_sendR  sÕ   è è € å˜'¥4Ñ(Ô(ÐAÐAÐ*AÑAÔAÐAØ×$Ò$ UÑ+Ô+ÐAÐAÐ-AÑAÔAÐAà×ÒÑÔÐà”{—’ u­c©e¬eÑ4Ô4ð 	ð 	ˆGðØ—i’i ¨Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1øÝð ð ð Ø�ðøøøð	ð 	s   Á?BÂ
B)Â(B))rB   r}   rA   N)r–   )r:   r;   r<   r=   r   Ú
extensionsr‘   rh   r£   r“   r„   r­   r§   r²   rµ   r·   Ú__classcell__)rƒ   s   @r   r|   r|   ¾   sÿ   ø€ € € € € ðð ð ØØØð)ð )ð )ð )ð )ð )ð( ˜GÐ$€JðHð Hð Hð&ð ð ð(
ð 
ð 
ð 
ð4ð 4ð 4ð<ð ð ðð ð ð&ð &ð &ð	2ð 	2ð 	2ð	'ð 	'ð 	'ðð ð ð ð ð ð r   r|   c                 ó@   — 	 t           |          S # t          $ r Y dS w xY w)zL
    Returns a channel layer by alias, or None if it is not configured.
    N)Úchannel_layersr(   )Úaliass    r   Úget_channel_layerr½   `  s4   € ðÝ˜eÔ$Ð$øÝð ð ð Øˆtˆtðøøøs   ‚ �
œ)rŠ   rO   rš   rM   rœ   rŽ   Úcopyr   Údjango.confr   Údjango.core.signalsr   Údjango.utils.module_loadingr   r€   r   Ú
exceptionsr	   r
   r   r@   r|   r½   r»   r-   r   r   ú<module>rÃ      sp  ðØ €€€Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð à  Ð  Ð  Ð  Ð  Ð  Ø /Ð /Ð /Ð /Ð /Ð /Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5à *Ð *Ð *Ð *Ð *Ð *à =Ð =Ð =Ð =Ð =Ð =Ð =Ð =ðJð Jð Jð Jð Jñ Jô Jð JðZ\ð \ð \ð \ð \ñ \ô \ð \ð~_ð _ð _ð _ð _Ð+ñ _ô _ð _ðD 2ð ð ð ð ð %Ð$Ñ&Ô&€€€r   