U
    
ڲg                     @   s|   d Z ddlZddlZddlZddlmZ ddlZedZG dd dejj	Z
G dd dZG d	d
 d
ZG dd dZdS )zzSSEClient module to stream realtime updates from the Firebase Database.

Based on a similar implementation from Pyrebase.
    N)	transportz\r\n\r\n|\r\r|\n\nc                       s(   e Zd ZdZ fddZdd Z  ZS )KeepAuthSessionzIA session that does not drop authentication on redirects between domains.c                    s   t t| | d S N)superr   __init__)selfZ
credential	__class__ =/tmp/pip-unpacked-wheel-p0r7i5ii/firebase_admin/_sseclient.pyr   $   s    zKeepAuthSession.__init__c                 C   s   d S r   r
   )r   prepared_requestresponser
   r
   r   rebuild_auth'   s    zKeepAuthSession.rebuild_auth)__name__
__module____qualname____doc__r   r   __classcell__r
   r
   r   r   r   !   s   r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zedd	 Zed
d Z	dS )_EventBufferz6A helper class for buffering and parsing raw SSE data.c                 C   s   g | _ d| _d S N )_buffer_tailr   r
   r
   r   r   .   s    z_EventBuffer.__init__c                 C   s.   | j | |  j|7  _| jdd  | _d S )N)r   appendr   )r   charr
   r
   r   r   2   s    z_EventBuffer.appendc                 C   s6   | j d\}}}|| }t|| _|dd  | _d S )N
r   )buffer_string
rpartitionlistr   r   )r   headsep_remr
   r
   r   truncate7   s    
z_EventBuffer.truncatec                 C   s(   | j dd  }|dkp&|dkp&| j dkS )N

zz

)r   )r   Zlast_two_charsr
   r
   r   is_end_of_field=   s    z_EventBuffer.is_end_of_fieldc                 C   s   d | jS r   )joinr   r   r
   r
   r   r   B   s    z_EventBuffer.buffer_stringN)
r   r   r   r   r   r   r%   propertyr(   r   r
   r
   r
   r   r   +   s   
r   c                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )	SSEClientzSSE client implementation.  c                 K   s^   || _ || _|| _|| _d| _d| _d| _| jdi }d|d< d|d< || jd< |   dS )	a  Initializes the SSEClient.

        Args:
          url: The remote url to connect to.
          session: The requests session.
          retry: The retry interval in milliseconds (optional).
          **kwargs: Extra kwargs that will be sent to ``requests.get()`` (optional).
        TNr   headerszno-cachezCache-Controlztext/event-streamAccept)	urlsessionretryrequests_kwargsshould_connectlast_idbufget_connect)r   r/   r0   r1   kwargsr-   r
   r
   r   r   J   s    	
zSSEClient.__init__c                 C   s   d| _ d| _| j  dS )zCloses the SSEClient instance.Fr   N)r3   r1   respcloser   r
   r
   r   r:   c   s    zSSEClient.closec                 C   s`   | j rV| jr| j| jd d< | jj| jfddi| j| _| jjdd| _| j	  nt
 dS )z&Connects to the server using requests.r-   zLast-Event-IDstreamT)decode_unicodeN)r3   r4   r2   r0   r6   r/   r9   iter_contentresp_iteratorraise_for_statusStopIterationr   r
   r
   r   r7   i   s    zSSEClient._connectc                 C   s   | S r   r
   r   r
   r
   r   __iter__t   s    zSSEClient.__iter__c              	   C   s   t t| js|t }|jstzt| j}|| W q t	t
jfk
rp   t| jd  |   |  Y qY qX q|j| _t t| j}|d }d|dd  | _t|}|jdkr|   d S |jdkrd S |jr|j| _|jr|j| _|S )Ng     @@r   r'      zcredential is no longer validnull)researchend_of_fieldr5   r   r(   nextr>   r   r@   requestsRequestExceptiontimesleepr1   r7   r%   r   splitr)   Eventparsedataevent_idr4   )r   Ztemp_buffernextcharrL   r!   eventr
   r
   r   __next__w   s4    



zSSEClient.__next__c                 C   s   |   S r   )rS   r   r
   r
   r   rG      s    zSSEClient.nextN)r,   )
r   r   r   r   r   r:   r7   rA   rS   rG   r
   r
   r
   r   r+   G   s   
%r+   c                   @   s0   e Zd ZdZedZd
ddZedd	 Z	dS )rM   z)Event represents the events fired by SSE.z#(?P<name>[^:]*):?( ?(?P<value>.*))?r   messageNc                 C   s   || _ || _|| _|| _d S r   )rO   
event_typerP   r1   )r   rO   rU   rP   r1   r
   r
   r   r      s    zEvent.__init__c                 C   s   |  }| dD ]}| j|}|dkr:td| t q| d }| d }|dkr\q|dkr|jr|d|j|f |_q||_q|d	kr||_q|d
kr||_	q|dkrt
||_q|S )zGiven a possibly-multiline string representing an SSE message, parses it
        and returns an Event object.

        Args:
          raw: the raw data to parse.

        Returns:
          Event: A new ``Event`` with the parameters initialized.
        r   NzInvalid SSE line: "%s"namevaluer   rO   z%s
%srR   idr1   )rL   sse_line_patternmatchwarningswarnSyntaxWarning	groupdictrO   rU   rP   intr1   )clsrawrR   linerZ   rV   rW   r
   r
   r   rN      s*    zEvent.parse)r   rT   NN)
r   r   r   r   rD   compilerY   r   classmethodrN   r
   r
   r
   r   rM      s
   

rM   )r   rD   rJ   r[   Zgoogle.authr   rH   rc   rF   ZAuthorizedSessionr   r   r+   rM   r
   r
   r
   r   <module>   s   

Y