o
    ,=jYe  ã                   @  s¶  d dl m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Zd dl	m
Z
 d dlmZmZ d dlmZ d dlmZmZmZ ejZe e¡ZdZi d	d “d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“d$d%“d&d'“d(d)“d*d+i¥Zd,Ze
je
je
je
je
je
j e
j!e
j"fZ#e
jfZ$e %d-d.d/g¡Z&G d0d1„ d1e'ƒZ(G d2d3„ d3eƒZ)G d4d5„ d5e'ƒZ*G d6d7„ d7e'ƒZ+d8d9„ Z,d:d;„ Z-d<d=„ Z.d>d?„ Z/G d@dA„ dAe'ƒZ0dS )Bé    )ÚannotationsN)ÚEnum)Ú
exceptions)ÚBackgroundConsumerÚResumableBidiRpc)Ú_helpers)ÚListenRequestÚTargetÚTargetChangeiyP  ÚOKÚ	CANCELLEDé   ÚUNKNOWNé   ZINVALID_ARGUMENTé   ZDEADLINE_EXCEEDEDé   Ú	NOT_FOUNDé   ZALREADY_EXISTSé   ZPERMISSION_DENIEDé   ZUNAUTHENTICATEDé   ZRESOURCE_EXHAUSTEDé   ZFAILED_PRECONDITIONé	   ZABORTEDé
   ZOUT_OF_RANGEé   ZUNIMPLEMENTEDé   ZINTERNALé   ÚUNAVAILABLEé   Z	DATA_LOSSé   Z
DO_NOT_USEéÿÿÿÿzThread-OnRpcTerminatedÚDocTreeEntryÚvalueÚindexc                   @  sT   e 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S )ÚWatchDocTreec                 C  s   i | _ d| _d S )Nr   )Ú_dictÚ_index©Úself© r)   úiC:\Users\psant\Downloads\Anu Raj Backend\school\venv\Lib\site-packages\google/cloud/firestore_v1/watch.pyÚ__init__O   s   
zWatchDocTree.__init__c                 C  s   t | j ¡ ƒS ©N)Úlistr%   Úkeysr'   r)   r)   r*   r.   S   s   zWatchDocTree.keysc                 C  s"   t ƒ }| j ¡ |_| j|_|} | S r,   )r$   r%   Úcopyr&   )r(   Zwdtr)   r)   r*   Ú_copyV   s
   zWatchDocTree._copyc                 C  s,   |   ¡ } t|| jƒ| j|< |  jd7  _| S )Nr   )r0   r!   r&   r%   )r(   Úkeyr"   r)   r)   r*   Úinsert]   s   zWatchDocTree.insertc                 C  s
   | j | S r,   ©r%   ©r(   r1   r)   r)   r*   Úfindc   ó   
zWatchDocTree.findc                 C  s   |   ¡ } | j|= | S r,   )r0   r%   r4   r)   r)   r*   Úremovef   s   zWatchDocTree.removec                 c  s   � | j D ]}|V  qd S r,   r3   ©r(   Úkr)   r)   r*   Ú__iter__k   s   €
ÿzWatchDocTree.__iter__c                 C  s
   t | jƒS r,   )Úlenr%   r'   r)   r)   r*   Ú__len__o   r6   zWatchDocTree.__len__c                 C  s
   || j v S r,   r3   r8   r)   r)   r*   Ú__contains__r   r6   zWatchDocTree.__contains__N)Ú__name__Ú
__module__Ú__qualname__r+   r.   r0   r2   r5   r7   r:   r<   r=   r)   r)   r)   r*   r$   K   s    r$   c                   @  s   e Zd ZdZdZdZdS )Ú
ChangeTyper   r   r   N)r>   r?   r@   ÚADDEDÚREMOVEDÚMODIFIEDr)   r)   r)   r*   rA   v   s    rA   c                   @  ó   e Zd Zdd„ ZdS )ÚDocumentChangec                 C  s   || _ || _|| _|| _dS )z±DocumentChange

        Args:
            type (ChangeType):
            document (document.DocumentSnapshot):
            old_index (int):
            new_index (int):
        N)ÚtypeÚdocumentÚ	old_indexÚ	new_index)r(   rG   rH   rI   rJ   r)   r)   r*   r+   }   s   

zDocumentChange.__init__N©r>   r?   r@   r+   r)   r)   r)   r*   rF   |   ó    rF   c                   @  rE   )ÚWatchResultc                 C  s   || _ || _|| _d S r,   )ÚsnapshotÚnameÚchange_type)r(   rN   rO   rP   r)   r)   r*   r+   Ž   s   
zWatchResult.__init__NrK   r)   r)   r)   r*   rM   �   rL   rM   c                 C  s   t | tjƒrt | ¡S | S )z(Wraps a gRPC exception class, if needed.N)Ú
isinstanceÚgrpcZRpcErrorr   Zfrom_grpc_error)Ú	exceptionr)   r)   r*   Ú_maybe_wrap_exception”   s   
rT   c                 C  s   | |ksJ dƒ‚dS )Nz+Document watches only support one document.r   r)   )Zdoc1Zdoc2r)   r)   r*   Údocument_watch_comparator›   s   rU   c                 C  ó   t | ƒ}t|tƒS r,   )rT   rQ   Ú_RECOVERABLE_STREAM_EXCEPTIONS©rS   Úwrappedr)   r)   r*   Ú_should_recover    ó   
rZ   c                 C  rV   r,   )rT   rQ   Ú_TERMINATING_STREAM_EXCEPTIONSrX   r)   r)   r*   Ú_should_terminate¥   r[   r]   c                
   @  sð   e Zd Zdd„ Zdd„ Zedd„ ƒZedd„ ƒZd	d
„ Zdd„ Z	e
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ejeejeejeejeejeiZd d!„ Zd"d#„ Zd$d%„ Zed&d'„ ƒZd(d)„ Z d*d+„ Z!d,d-„ Z"dS )/ÚWatchc                 C  sz   || _ || _|| _|| _|| _|| _|j| _t 	¡ | _
d| _|  |j¡ d| _tƒ | _i | _i | _d| _d| _|  ¡  dS )aÕ  
        Args:
            firestore:
            target:
            comparator:
            snapshot_callback: Callback method to process snapshots.
                Args:
                    docs (List(DocumentSnapshot)): A callback that returns the
                        ordered list of documents stored in this snapshot.
                    changes (List(str)): A callback that returns the list of
                        changed documents since the last snapshot delivered for
                        this watch.
                    read_time (string): The ISO 8601 time at which this
                        snapshot was obtained.

            document_snapshot_cls: factory for instances of DocumentSnapshot
        FN)Z_document_referenceÚ
_firestoreÚ_targetsÚ_comparatorÚ_document_snapshot_clsÚ_snapshot_callbackZ_firestore_apiÚ_apiÚ	threadingÚLockÚ_closingÚ_closedÚ_set_documents_pfxÚ_database_stringÚresume_tokenr$   Údoc_treeÚdoc_mapÚ
change_mapÚcurrentÚ
has_pushedÚ_init_stream)r(   Zdocument_referenceZ	firestoreÚtargetZ
comparatorÚsnapshot_callbackÚdocument_snapshot_clsr)   r)   r*   r+   «   s"   
zWatch.__init__c                 C  sP   | j }t| jjjtt|| jjd�| _	| j	 
| j¡ t| j	| jƒ| _| j ¡  d S )N)Z	start_rpcZshould_recoverZshould_terminateZinitial_requestÚmetadata)Ú_get_rpc_requestr   rd   Ú
_transportÚlistenrZ   r]   r_   Z_rpc_metadataÚ_rpcÚadd_done_callbackÚ_on_rpc_doner   Úon_snapshotÚ	_consumerÚstart)r(   Zrpc_requestr)   r)   r*   rq   é   s   ûÿzWatch._init_streamc                 C  s"   | ||j d|jgitdœt||ƒS )a¹  
        Creates a watch snapshot listener for a document. snapshot_callback
        receives a DocumentChange object, but may also start to get
        targetChange and such soon

        Args:
            document_ref: Reference to Document
            snapshot_callback: callback to be called on snapshot
            document_snapshot_cls: class to make snapshots with
            reference_class_instance: class make references

        Ú	documents)r   Ú	target_idN)Ú_clientÚ_document_pathÚWATCH_TARGET_IDrU   )ÚclsÚdocument_refrs   rt   r)   r)   r*   Úfor_documentü   s   
þ÷zWatch.for_documentc                 C  s>   |j  ¡ \}}tj|| ¡ d�}| ||j|jtdœ|j||ƒS )N)ÚparentZstructured_query)Úqueryr€   )	Ú_parentZ_parent_infor	   ZQueryTargetZ_to_protobufr�   Ú_pbrƒ   ra   )r„   rˆ   rs   rt   Úparent_pathÚ_Zquery_targetr)   r)   r*   Ú	for_query  s   ÿ
úzWatch.for_queryc                 C  s8   | j d ur| j | jd< n| j dd ¡ t| jj| jd�S )Nrk   )ZdatabaseZ
add_target)rk   r`   Úpopr   r_   rj   r'   r)   r)   r*   rv   +  s   

ÿzWatch._get_rpc_requestc                 C  s   |› d�| _ t| j ƒ| _d S )Nz/documents/)Ú_documents_pfxr;   Ú_documents_pfx_len)r(   Zdatabase_stringr)   r)   r*   ri   5  s   zWatch._set_documents_pfxc                 C  s   | j duo| j jS )z¸bool: True if this manager is actively streaming.

        Note that ``False`` does not indicate this is complete shut down,
        just that it stopped getting new messages.
        N)r}   Ú	is_activer'   r)   r)   r*   r‘   9  s   zWatch.is_activeNc                 C  sÔ   | j �I | jr	 W d  ƒ dS | jr$| jr t d¡ | j ¡  d| j_d| _d| _| j	r:| j	 
¡  d| j	_g | j	_d| _	d| _t d¡ W d  ƒ n1 sOw   Y  |rht d| ¡ t|tƒrd|‚t|ƒ‚dS )a  Stop consuming messages and shutdown all helper threads.

        This method is idempotent. Additional calls will have no effect.

        Args:
            reason (Any): The reason to close this. If None, this is considered
                an "intentional" shutdown.
        NzStopping consumer.TzFinished stopping manager.zreason for closing: %s)rg   rh   r}   r‘   Ú_LOGGERÚdebugÚstopZ_on_responserc   ry   ÚcloseZ_initial_requestÚ
_callbacksrQ   Ú	ExceptionÚRuntimeError)r(   Úreasonr)   r)   r*   r•   B  s2   	þ


í
ûzWatch.closec                 C  s:   t  d¡ t|ƒ}tjt| jd|id�}d|_| ¡  dS )a
  Triggered whenever the underlying RPC terminates without recovery.

        This is typically triggered from one of two threads: the background
        consumer thread (when calling ``recv()`` produces a non-recoverable
        error) or the grpc management thread (when cancelling the RPC).

        This method is *non-blocking*. It will start another thread to deal
        with shutting everything down. This is to prevent blocking in the
        background consumer and preventing it from being ``joined()``.
        z.RPC termination has signaled manager shutdown.r™   )rO   rr   ÚkwargsTN)	r’   ÚinforT   re   ÚThreadÚ_RPC_ERROR_THREAD_NAMEr•   Údaemonr~   )r(   ÚfutureÚthreadr)   r)   r*   r{   g  s   
ÿzWatch._on_rpc_donec                 C  s   |   ¡  d S r,   )r•   r'   r)   r)   r*   Úunsubscribez  s   zWatch.unsubscribec                 C  sR   t  d¡ |jd u pt|jƒdk}|r#|jr%| jr'|  |j|j¡ d S d S d S d S )Nz%on_snapshot: target change: NO_CHANGEr   )r’   r“   Ú
target_idsr;   Ú	read_timero   Úpushrk   )r(   Útarget_changeZno_target_idsr)   r)   r*   Ú$_on_snapshot_target_change_no_change}  s   
ÿûz*Watch._on_snapshot_target_change_no_changec                 C  s,   t  d¡ |jd }|tkrtd| ƒ‚d S )Nzon_snapshot: target change: ADDr   z&Unexpected target ID %s sent by server)r’   r“   r¢   rƒ   r˜   )r(   r¥   r€   r)   r)   r*   Ú_on_snapshot_target_change_addŠ  s
   

ÿz$Watch._on_snapshot_target_change_addc                 C  sJ   t  d¡ |jjr|jj}|jj}nd}d}d||f }t|ƒt ||¡‚)Nz"on_snapshot: target change: REMOVEr   zinternal errorzError %s:  %s)r’   r“   ÚcauseÚcodeÚmessager˜   r   Zfrom_grpc_status)r(   r¥   r©   rª   Úerror_messager)   r)   r*   Ú!_on_snapshot_target_change_remove�  s   


ÿz'Watch._on_snapshot_target_change_removec                 C  s   t  d¡ |  ¡  d S )Nz!on_snapshot: target change: RESET)r’   r“   Ú_reset_docs©r(   r¥   r)   r)   r*   Ú _on_snapshot_target_change_reset   s   
z&Watch._on_snapshot_target_change_resetc                 C  s   t  d¡ d| _d S )Nz#on_snapshot: target change: CURRENTT)r’   r“   ro   r®   r)   r)   r*   Ú"_on_snapshot_target_change_current¥  s   

z(Watch._on_snapshot_target_change_currentc                 C  s   |  | j¡r|| jd … }|S r,   )Ú
startswithr�   r�   )r(   Údocument_namer)   r)   r*   Ú_strip_document_pfx±  s   zWatch._strip_document_pfxc              
   C  sl  | j  ¡ rdS |du r|  ¡  dS |j}| d¡}|dkri|jj}t d|› �¡ | j	 
|¡}|du rJd|› �}t d|› �¡ | jt|ƒd� dS z	|| |jƒ W dS  tyh } z	t d|› �¡ ‚ d}~ww |d	krÄt d
¡ t|jjv }t|jjv }	|jj}
|r²t d¡ t |
j| j¡}|  |
j¡}| j |¡}| j||dd|
j|
jd�}|| j|
j< dS |	rÂt d¡ tj| j|
j< dS dS |dkrÙt d¡ |jj}tj| j|< dS |dkrît d¡ |j j}tj| j|< dS |dk�r"t d¡ |j!j"|  #¡ k�r t d¡ t$j%t&| jd�}| '¡  | (¡  |  )¡  |  *¡  dS dS t d¡ d|› �}| jt|ƒd� dS )aS  Process a response from the bi-directional gRPC stream.

        Collect changes and push the changes in a batch to the customer
        when we receive 'current' from the listen response.

        Args:
            proto(`google.cloud.firestore_v1.types.ListenResponse`):
                Callback method that receives a object to
        NZresponse_typer¥   zon_snapshot: target change: zUnknown target change type: zon_snapshot: )r™   zmeth(proto) exc: Údocument_changezon_snapshot: document changez%on_snapshot: document change: CHANGEDT)Ú	referenceÚdataÚexistsr£   Úcreate_timeÚupdate_timez%on_snapshot: document change: REMOVEDÚdocument_deletez$on_snapshot: document change: DELETEÚdocument_removez$on_snapshot: document change: REMOVEÚfilterzon_snapshot: filter updatez%Filter mismatch -- restarting stream.)rO   rr   zUNKNOWN TYPE. UHOHzUnknown listen response type: )+rg   Úlockedr•   rŠ   Z
WhichOneofr¥   Útarget_change_typer’   r“   Ú_target_changetype_dispatchÚgetr›   Ú
ValueErrorr—   rƒ   r´   r¢   Zremoved_target_idsrH   r   Zdecode_dictÚfieldsr_   r³   rO   rb   r¸   r¹   rn   rA   rC   rº   r»   r¼   ÚcountÚ_current_sizere   rœ   r�   r~   Újoinr­   rq   )r(   ÚprotoZpbÚwhichr¾   Úmethrª   Zexc2ÚchangedÚremovedrH   r¶   r²   r…   rN   rO   r    r)   r)   r*   r|   ¶  sŠ   



€þ

ú
þ




þô

zWatch.on_snapshotc                 C  s’   |   | j| j|¡\}}}|  | j| j|||¡\}}}| jr!t|ƒr9t | j	¡}	t
| ¡ |	d�}
|  |
||¡ d| _|| _|| _| j ¡  || _dS )z Invoke the callback with a new snapshot

        Build the sntapshot from the current set of changes.

        Clear the current changes on completion.
        ©r1   TN)Ú_extract_changesrm   rn   Ú_compute_snapshotrl   rp   r;   Ú	functoolsÚ
cmp_to_keyra   Úsortedr.   rc   Úclearrk   )r(   r£   Znext_resume_tokenÚdeletesÚaddsÚupdatesÚupdated_treeÚupdated_mapÚappliedChangesr1   r.   r)   r)   r*   r¤   '  s   

ÿ
ÿ

z
Watch.pushc                 C  s€   g }g }g }|  ¡ D ]0\}}|tjkr|| v r| |¡ q
|| v r.|d ur(||_| |¡ q
|d ur5||_| |¡ q
|||fS r,   )ÚitemsrA   rC   Úappendr£   )rm   Úchangesr£   rÒ   rÓ   rÔ   rO   r"   r)   r)   r*   rÌ   D  s    

€
zWatch._extract_changesc                   s  |}|}t |ƒt |ƒksJ dƒ‚dd„ ‰dd„ ‰ ‡ ‡fdd„}g }	t | j¡}
t|ƒ}|D ]}ˆ|||ƒ\}}}|	 |¡ q-t||
d�}t d	¡ |D ]}t d
¡ ˆ |||ƒ\}}}|	 |¡ qKt||
d�}|D ]}||||ƒ\}}}|d ur}|	 |¡ qit |ƒt |ƒksŠJ dƒ‚|||	fS )NzJThe document tree and document map should have the same number of entries.c                 S  sP   | |v sJ dƒ‚|  | ¡}| |¡}|j}| |¡}|| = ttj||dƒ||fS )z–
            Applies a document delete to the document tree and document map.
            Returns the corresponding DocumentChange event.
            z!Document to delete does not existr    N)rÀ   r5   r#   r7   rF   rA   rC   )rO   rÕ   rÖ   Úold_documentÚexistingrI   r)   r)   r*   Ú
delete_docd  s   


ýz+Watch._compute_snapshot.<locals>.delete_docc                 S  sN   | j j}||vsJ dƒ‚| | d¡}| | ¡j}| ||< ttj| d|ƒ||fS )z—
            Applies a document add to the document tree and the document map.
            Returns the corresponding DocumentChange event.
            zDocument to add already existsNr    )rµ   r‚   r2   r5   r#   rF   rA   rB   )Únew_documentrÕ   rÖ   rO   rJ   r)   r)   r*   Úadd_docv  s   ýz(Watch._compute_snapshot.<locals>.add_docc                   sv   | j j}||v sJ dƒ‚| |¡}|j| jkr6ˆ|||ƒ\}}}ˆ | ||ƒ\}}}ttj| |j|jƒ||fS d||fS )z»
            Applies a document modification to the document tree and the
            document map.
            Returns the DocumentChange event for successful modifications.
            z!Document to modify does not existN)	rµ   r‚   rÀ   r¹   rF   rA   rD   rI   rJ   )rÞ   rÕ   rÖ   rO   rÛ   Zremove_changeZ
add_change©rß   rÝ   r)   r*   Ú
modify_doc†  s(   

ÿ
ÿüø
z+Watch._compute_snapshot.<locals>.modify_docrË   zwalk over add_changeszin add_changeszQThe update document tree and document map should have the same number of entries.)r;   rÎ   rÏ   ra   rÐ   rÙ   r’   r“   )r(   rl   rm   Zdelete_changesZadd_changesZupdate_changesrÕ   rÖ   rá   r×   r1   rO   ZchangerN   r)   rà   r*   rÍ   Y  sH   ÿ!
ÿ


ÿ
ÿ
€ÿ
zWatch._compute_snapshotc                 C  s2   |   | j| jd¡\}}}t| jƒt|ƒ t|ƒ S )zsReturn the current count of all documents.

        Count includes the changes from the current changeMap.
        N)rÌ   rm   rn   r;   )r(   rÒ   rÓ   rŒ   r)   r)   r*   rÄ   Ê  s   zWatch._current_sizec                 C  sH   t  d¡ | j ¡  d| _| j ¡ D ]}|jj}t	j
| j|< qd| _dS )zG
        Helper to clear the docs on RESET or filter mismatch.
        zresetting documentsNF)r’   r“   rn   rÑ   rk   rl   r.   rµ   r‚   rA   rC   ro   )r(   rN   rO   r)   r)   r*   r­   Ò  s   


zWatch._reset_docsr,   )#r>   r?   r@   r+   rq   Úclassmethodr†   r�   rv   ri   Úpropertyr‘   r•   r{   r¡   r¦   r§   r¬   r¯   r°   ÚTargetChangeTypeZ	NO_CHANGEZADDZREMOVEÚRESETZCURRENTr¿   r³   r|   r¤   ÚstaticmethodrÌ   rÍ   rÄ   r­   r)   r)   r)   r*   r^   ª   sB    >




%ûq
qr^   )1Ú
__future__r   ÚcollectionsrÎ   Úloggingre   Úenumr   rR   Zgoogle.api_corer   Zgoogle.api_core.bidir   r   Zgoogle.cloud.firestore_v1r   Z)google.cloud.firestore_v1.types.firestorer   r	   r
   rä   Ú	getLoggerr>   r’   rƒ   ZGRPC_STATUS_CODEr�   ZAbortedZ	CancelledÚUnknownZDeadlineExceededZResourceExhaustedZInternalServerErrorZServiceUnavailableZUnauthenticatedrW   r\   Ú
namedtupler!   Úobjectr$   rA   rF   rM   rT   rU   rZ   r]   r^   r)   r)   r)   r*   Ú<module>   s�   
ÿþýüûúùø	÷
öõôóòñðïîø
+