o
    UgM3                     @   s   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
 d
ZG dd dZG dd deZefddZe ZdS )    N)deepcopy)settings)setting_changed)import_string)DEFAULT_CHANNEL_LAYER   )ChannelFullInvalidChannelLayerErrorc                   @   s\   e Zd ZdZdd Zdd Zedd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd ZdS )ChannelLayerManagerzR
    Takes a settings dictionary of backends and initialises them on request.
    c                 C   s   i | _ t| j d S N)backendsr   connect_reset_backendsself r   [/var/www/html/Testing_prj/Navya-Bakers/venv/lib/python3.10/site-packages/channels/layers.py__init__   s   zChannelLayerManager.__init__c                 K   s   |dkr	i | _ dS dS )zX
        Removes cached channel layers when the CHANNEL_LAYERS setting changes.
        CHANNEL_LAYERSN)r   )r   settingkwargsr   r   r   r      s   
z#ChannelLayerManager._reset_backendsc                 C   s   t tdi S )Nr   )getattrr   r   r   r   r   configs"   s   zChannelLayerManager.configsc                 C   s   | j | di }| ||S )z,
        Instantiate channel layer.
        CONFIG)r   get_make_backendr   nameconfigr   r   r   make_backend'   s   z ChannelLayerManager.make_backendc                 C   s:   z	| j | d }W n ty   td| w | ||S )zB
        Instantiate channel layer using its test config.
        TEST_CONFIGzNo TEST_CONFIG specified for %s)r   KeyErrorr	   r   r   r   r   r   make_test_backend.   s   z%ChannelLayerManager.make_test_backendc                 C   s   d| j | v rtd| zt| j | d }W n  ty%   td|  ty8   td| j | d |f 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 %r specified for %sr   )r   r	   r   r!   ImportError)r   r   r   backend_classr   r   r   r   8   s$   z!ChannelLayerManager._make_backendc                 C   s$   || j vr| || j |< | j | S r   )r   r   r   keyr   r   r   __getitem__L   s   

zChannelLayerManager.__getitem__c                 C   s
   || j v S r   )r   r'   r   r   r   __contains__Q   s   
z ChannelLayerManager.__contains__c                 C   s   | 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   r(   layeroldr   r   r   setT   s   
zChannelLayerManager.setN)__name__
__module____qualname____doc__r   r   propertyr   r   r"   r   r)   r*   r-   r   r   r   r   r
      s    

r
   c                   @   s   e Zd ZdZdZd*ddZdd Zd	d
 Zdd Ze	
dZe	
dZdde d d Zd+ddZdd Zd+ddZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) ZdS ),BaseChannelLayerzf
    Base channel layer class that others can inherit from, with useful
    common functionality.
    d   <   Nc                 C   s   || _ || _|p	i | _d S r   expirycapacitychannel_capacity)r   r7   r8   r9   r   r   r   r   g   s   zBaseChannelLayer.__init__c                 C   sN   g }|  D ]\}}t|dr|||f q|tt||f q|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   r9   resultpatternvaluer   r   r   compile_capacitiesl   s   
z#BaseChannelLayer.compile_capacitiesc                 C   s(   | j D ]\}}||r|  S q| 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.
        )r9   r:   r8   )r   channelrC   r8   r   r   r   get_capacity{   s
   
zBaseChannelLayer.get_capacityc                 C   s    t |trt|| jk rdS dS )NTF)
isinstancestrlenMAX_NAME_LENGTHr   r   r   r   r   match_type_and_length   s   z&BaseChannelLayer.match_type_and_lengthz!^[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                 C   sN   |  |rt| 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)rM   boolchannel_name_regexr:   endswith	TypeErrorinvalid_name_errorformat)r   r   receiver   r   r   valid_channel_name   s   
z#BaseChannelLayer.valid_channel_namec                 C   s0   |  |rt| j|rdS t| jd|)NTGroup)rM   rP   group_name_regexr:   rS   rT   rU   rL   r   r   r   valid_group_name   s   
z!BaseChannelLayer.valid_group_namec                    sF   |rdnd}t |t}|r|sJ dt fdd|D s!J dS )NTFznames must be a non-empty listc                 3   s    | ]
}j | d V  qdS ))rV   N)rW   ).0rF   rV   r   r   r   	<genexpr>   s    
z7BaseChannelLayer.valid_channel_names.<locals>.<genexpr>)rH   listall)r   namesrV   _non_empty_list_names_typer   r\   r   valid_channel_names   s   
z$BaseChannelLayer.valid_channel_namesc                 C   s"   d|v r|d| dd  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.
        rN   Nr   )findrL   r   r   r   non_local_name   s   zBaseChannelLayer.non_local_namec                    
   t d)Nz/send() should be implemented in a channel layerNotImplementedError)r   rF   messager   r   r   send      zBaseChannelLayer.sendc                    rf   )Nz2receive() should be implemented in a channel layerrg   )r   rF   r   r   r   rV      rk   zBaseChannelLayer.receivec                    rf   )Nz6new_channel() should be implemented in a channel layerrg   r   r   r   r   new_channel   s   zBaseChannelLayer.new_channelc                    rf   )Nz)flush() not implemented (flush extension)rg   r   r   r   r   flush   rk   zBaseChannelLayer.flushc                    rf   )Nz.group_add() not implemented (groups extension)rg   r   grouprF   r   r   r   	group_add   rk   zBaseChannelLayer.group_addc                    rf   )Nz2group_discard() not implemented (groups extension)rg   rn   r   r   r   group_discard   rk   zBaseChannelLayer.group_discardc                    rf   )Nz/group_send() not implemented (groups extension)rg   )r   ro   ri   r   r   r   
group_send   rk   zBaseChannelLayer.group_send)r5   r4   N)F)r.   r/   r0   r1   rK   r   rE   rG   rM   r>   r?   rQ   rY   rU   rT   rW   rZ   rc   re   rj   rV   rl   rm   rp   rq   rr   r   r   r   r   r3   _   s8    





r3   c                       s   e Zd ZdZ				d fdd	Zdd	gZd
d Zdd Zd ddZdd Z	dd Z
dd Zdd Zdd Zdd Zdd Z  ZS )!InMemoryChannelLayerz0
    In-memory channel layer implementation
    r5   Q r4   Nc                    s0   t  jd|||d| i | _i | _|| _d S )Nr6   r   )superr   channelsgroupsgroup_expiry)r   r7   rx   r8   r9   r   	__class__r   r   r      s   
zInMemoryChannelLayer.__init__rw   rm   c                    s   t |ts
J d| |sJ dd|vsJ | j|tj| |d}z|t		 | j
 t|f W dS  tjjyE   t|w )zF
        Send a message onto a (general or specific) channel.
        zmessage is not a dictChannel name not valid__asgi_channel__maxsizeN)rH   dictrW   rv   
setdefaultasyncioQueuerG   
put_nowaittimer7   r   queues	QueueFullr   )r   rF   ri   queuer   r   r   rj      s   "zInMemoryChannelLayer.sendc              
      s~   |  |sJ |   | j|tj| |d}z| I dH \}}W | r0| j	|d |S | r>| j	|d w w )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.
        r}   N)
rW   _clean_expiredrv   r   r   r   rG   r   emptypop)r   rF   r   _ri   r   r   r   rV     s   zInMemoryChannelLayer.receive	specific.c                    s"   d|d dd tdD f S )zx
        Returns a new channel name that can be used by something in our
        process as a specific channel.
        z%s.inmemory!%s c                 s   s    | ]	}t tjV  qd S r   )randomchoicestringascii_letters)r[   ir   r   r   r]   !  s    z3InMemoryChannelLayer.new_channel.<locals>.<genexpr>   )joinrange)r   prefixr   r   r   rl     s
   z InMemoryChannelLayer.new_channelc                 C   s   t | j D ]6\}}| s=|jd d t k r=|  | | | r.| j|d | s=|jd d t k sqt	t | j
 }| j D ]}t | D ]\}}|rd||k rd||d qTqLd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)r^   rv   r;   r   _queuer   
get_nowait_remove_from_groupsr   intrx   rw   values)r   rF   r   timeoutrv   r   	timestampr   r   r   r   &  s    
	z#InMemoryChannelLayer._clean_expiredc                    s   i | _ i | _d S r   )rv   rw   r   r   r   r   rm   B  s   
zInMemoryChannelLayer.flushc                    s   d S r   r   r   r   r   r   closeF  s   zInMemoryChannelLayer.closec                 C   s    | j  D ]}||d qdS )zW
        Removes a channel from all groups. Used when a message on it expires.
        N)rw   r   r   )r   rF   rv   r   r   r   r   J  s   z(InMemoryChannelLayer._remove_from_groupsc                    sJ   |  |s
J d| |sJ d| j|i  t | j| |< dS )z3
        Adds the channel name to a group.
        zGroup name not validr{   N)rZ   rW   rw   r   r   rn   r   r   r   rp   S  s
   zInMemoryChannelLayer.group_addc                    sb   |  |s
J d| |sJ d| j|d }|r-||d  |s/| j|d  d S d S d S )NzInvalid channel nameInvalid group name)rW   rZ   rw   r   r   )r   ro   rF   group_channelsr   r   r   rq   ^  s   z"InMemoryChannelLayer.group_discardc              	      s   t |ts
J d| |sJ d|   g }|| jv r4| j|  D ]}|t| 	|| q%t
|D ]}z|I d H  W q9 tyK   Y q9w d S )NzMessage is not a dictr   )rH   r   rZ   r   rw   keysr=   r   create_taskrj   as_completedr   )r   ro   ri   opsrF   send_resultr   r   r   rr   k  s   
zInMemoryChannelLayer.group_send)r5   rt   r4   N)r   )r.   r/   r0   r1   r   
extensionsrj   rV   rl   r   rm   r   r   rp   rq   rr   __classcell__r   r   ry   r   rs      s$    
	rs   c                 C   s    zt |  W S  ty   Y dS w )zL
    Returns a channel layer by alias, or None if it is not configured.
    N)channel_layersr!   )aliasr   r   r   get_channel_layer~  s
   
r   )r   r@   r   r>   r   r   copyr   django.confr   django.core.signalsr   django.utils.module_loadingr   rv   r   
exceptionsr   r	   r
   r3   rs   r   r   r   r   r   r   <module>   s$    Mv *
