3
ñ\ð]\  ã               @   s6   d dl Z d dlZd dlZejdƒZG dd„ deƒZdS )é    NZsocketioc               @   sš   e Zd Z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d„ Zdd„ Zdd„ Zdd„ Zdd„ Zd%dd„Zdd „ Zd!d"„ Zd#d$„ ZdS )&ÚBaseManagera]  Manage client connections.

    This class keeps track of all the clients and the rooms they are in, to
    support the broadcasting of messages. The data used by this class is
    stored in a memory structure, making it appropriate only for single process
    services. More sophisticated storage backends can be implemented by
    subclasses.
    c             C   s"   d | _ d | _i | _i | _i | _d S )N)ÚloggerÚserverÚroomsÚ	callbacksÚpending_disconnect)Úself© r	   ú@/tmp/pip-build-mqc4i71p/python-socketio/socketio/base_manager.pyÚ__init__   s
    zBaseManager.__init__c             C   s
   || _ d S )N)r   )r   r   r	   r	   r
   Ú
set_server   s    zBaseManager.set_serverc             C   s   dS )zqInvoked before the first request is received. Subclasses can add
        their initialization code here.
        Nr	   )r   r	   r	   r
   Ú
initialize   s    zBaseManager.initializec             C   s   t j| jƒS )z3Return an iterable with the active namespace names.)ÚsixÚiterkeysr   )r   r	   r	   r
   Úget_namespaces"   s    zBaseManager.get_namespacesc             c   s0   x*t j| j| | jƒ ƒD ]\}}|V  qW dS )z:Return an iterable with the active participants in a room.N)r   Ú	iteritemsr   Úcopy)r   Ú	namespaceÚroomÚsidÚactiver	   r	   r
   Úget_participants&   s    "zBaseManager.get_participantsc             C   s    | j ||dƒ | j |||ƒ dS )z,Register a client connection to a namespace.N)Ú
enter_room)r   r   r   r	   r	   r
   Úconnect+   s    zBaseManager.connectc             C   sH   || j kr|| j | krdS y| j| d  | S  tk
rB   Y nX d S )NF)r   r   ÚKeyError)r   r   r   r	   r	   r
   Úis_connected0   s    
zBaseManager.is_connectedc             C   s(   || j krg | j |< | j | j|ƒ dS )zïPut the client in the to-be-disconnected list.

        This allows the client data structures to be present while the
        disconnect handler is invoked, but still recognize the fact that the
        client is soon going away.
        N)r   Úappend)r   r   r   r	   r	   r
   Úpre_disconnect:   s    

zBaseManager.pre_disconnectc             C   sæ   || j krdS g }x2tj| j | jƒ ƒD ]\}}||kr(|j|ƒ q(W x|D ]}| j|||ƒ qLW || jkr || j| kr | j| |= t| j| ƒdkr | j|= || jkrâ|| j| krâ| j| j	|ƒ t| j| ƒdkrâ| j|= dS )z.Register a client disconnect from a namespace.Nr   )
r   r   r   r   r   Ú
leave_roomr   Úlenr   Úremove)r   r   r   r   Ú	room_namer   r	   r	   r
   Ú
disconnectE   s"    


zBaseManager.disconnectc             C   sF   || j kri | j |< || j | kr0i | j | |< d| j | | |< dS )zAdd a client to a room.TN)r   )r   r   r   r   r	   r	   r
   r   Y   s
    

zBaseManager.enter_roomc             C   sj   yP| j | | |= t| j | | ƒdkrN| j | |= t| j | ƒdkrN| j |= W n tk
rd   Y nX dS )zRemove a client from a room.r   N)r   r   r   )r   r   r   r   r	   r	   r
   r   a   s    zBaseManager.leave_roomc             C   sB   y(x"| j ||ƒD ]}| j|||ƒ qW W n tk
r<   Y nX dS )z$Remove all participants from a room.N)r   r   r   )r   r   r   r   r	   r	   r
   Ú
close_rooml   s
    zBaseManager.close_roomc             C   sb   g }yDx>t j| j| ƒD ]*\}}|dk	r||kr|| r|j|ƒ qW W n tk
r\   Y nX |S )z Return the rooms a client is in.N)r   r   r   r   r   )r   r   r   Úrr!   r   r	   r	   r
   Ú	get_roomst   s    zBaseManager.get_roomsNc       
      K   s~   || j ks|| j | krdS t|tƒs,|g}xL| j||ƒD ]<}||kr:|dk	r^| j|||ƒ}	nd}	| jj|||||	ƒ q:W dS )zaEmit a message to a single client, a room, or all the clients
        connected to the namespace.N)r   Ú
isinstanceÚlistr   Ú_generate_ack_idr   Z_emit_internal)
r   ÚeventÚdatar   r   Zskip_sidÚcallbackÚkwargsr   Úidr	   r	   r
   Úemit   s    
zBaseManager.emitc             C   sb   d}y| j | | | }W n" tk
r<   | jƒ jdƒ Y nX | j | | |= |dk	r^||Ž  dS )zInvoke an application callback.Nz$Unknown callback received, ignoring.)r   r   Ú_get_loggerÚwarning)r   r   r   r-   r*   r+   r	   r	   r
   Útrigger_callback�   s    zBaseManager.trigger_callbackc             C   sp   |pd}|| j kri | j |< || j | krBdtjdƒi| j | |< tj| j | | d ƒ}|| j | | |< |S )z/Generate a unique identifier for an ACK packet.ú/r   é   )r   Ú	itertoolsÚcountr   Únext)r   r   r   r+   r-   r	   r	   r
   r(   œ   s    

zBaseManager._generate_ack_idc             C   s"   | j r| j S | jr| jj S tS dS )zlGet the appropriate logger

        Prevents uninitialized servers in write-only mode from failing.
        N)r   r   Údefault_logger)r   r	   r	   r
   r/   §   s
    zBaseManager._get_logger)NNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   r"   r   r   r#   r%   r.   r1   r(   r/   r	   r	   r	   r
   r   	   s&   
 
r   )r4   Úloggingr   Ú	getLoggerr7   Úobjectr   r	   r	   r	   r
   Ú<module>   s   
