
    Ѯhnd                        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j&                  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j2                  ej4                  ej6                  ej8                  ej:                  ej<                  ej>                  ej@                  fZ!ej4                  fZ" e jF                  d,d-d.g      Z$ G d/ d0e%      Z& G d1 d2e      Z' G d3 d4e%      Z( G d5 d6e%      Z)d7 Z*d8 Z+d9 Z,d: Z- G d; d<e%      Z.y)=    N)Enum)
exceptions)BackgroundConsumerResumableBidiRpc)_helpers)ListenRequestTargetTargetChangeiyP  OK	CANCELLED   UNKNOWN   INVALID_ARGUMENT   DEADLINE_EXCEEDED   	NOT_FOUND   ALREADY_EXISTS   PERMISSION_DENIED   UNAUTHENTICATED   RESOURCE_EXHAUSTED   FAILED_PRECONDITION	   ABORTED
   OUT_OF_RANGE   UNIMPLEMENTED   INTERNAL   UNAVAILABLE   	DATA_LOSS   
DO_NOT_USEzThread-OnRpcTerminatedDocTreeEntryvalueindexc                   B    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)WatchDocTreec                      i | _         d| _        y )Nr   )_dict_indexselfs    q/home/www/academy-backend.kofcorporation.com/venv/lib/python3.12/site-packages/google/cloud/firestore_v1/watch.py__init__zWatchDocTree.__init__N   s    
    c                 H    t        | j                  j                               S N)listr4   keysr6   s    r8   r>   zWatchDocTree.keysR   s    DJJOO%&&r:   c                 ~    t               }| j                  j                         |_        | j                  |_        |} | S r<   )r2   r4   copyr5   )r7   wdts     r8   _copyzWatchDocTree._copyU   s0    nJJOO%	[[
r:   c                     | j                         } t        || j                        | j                  |<   | xj                  dz  c_        | S )Nr   )rB   r.   r5   r4   )r7   keyr/   s      r8   insertzWatchDocTree.insert\   s8    zz|&udkk:

3qr:   c                      | j                   |   S r<   r4   r7   rD   s     r8   findzWatchDocTree.findb   s    zz#r:   c                 @    | j                         } | j                  |= | S r<   )rB   r4   rH   s     r8   removezWatchDocTree.removee   s    zz|JJsOr:   c              #   6   K   | j                   D ]  }|  y wr<   rG   r7   ks     r8   __iter__zWatchDocTree.__iter__j   s      	AG	s   c                 ,    t        | j                        S r<   )lenr4   r6   s    r8   __len__zWatchDocTree.__len__n   s    4::r:   c                     || j                   v S r<   rG   rM   s     r8   __contains__zWatchDocTree.__contains__q   s    DJJr:   N)__name__
__module____qualname__r9   r>   rB   rE   rI   rK   rO   rR   rT    r:   r8   r2   r2   J   s/    '
r:   r2   c                       e Zd ZdZdZdZy)
ChangeTyper   r   r   N)rU   rV   rW   ADDEDREMOVEDMODIFIEDrX   r:   r8   rZ   rZ   u   s    EGHr:   rZ   c                       e Zd Zd Zy)DocumentChangec                 <    || _         || _        || _        || _        y)zDocumentChange

        Args:
            type (ChangeType):
            document (document.DocumentSnapshot):
            old_index (int):
            new_index (int):
        N)typedocument	old_index	new_index)r7   ra   rb   rc   rd   s        r8   r9   zDocumentChange.__init__|   s      	 ""r:   NrU   rV   rW   r9   rX   r:   r8   r_   r_   {   s    #r:   r_   c                       e Zd Zd Zy)WatchResultc                 .    || _         || _        || _        y r<   )snapshotnamechange_type)r7   ri   rj   rk   s       r8   r9   zWatchResult.__init__   s     	&r:   Nre   rX   r:   r8   rg   rg      s    'r:   rg   c                 d    t        | t        j                        rt        j                  |       S | S )z(Wraps a gRPC exception class, if needed.)
isinstancegrpcRpcErrorr   from_grpc_error)	exceptions    r8   _maybe_wrap_exceptionrr      s'    )T]]+)))44r:   c                     | |k(  sJ d       y)Nz+Document watches only support one document.r   rX   )doc1doc2s     r8   document_watch_comparatorrv      s    4<FFF<r:   c                 8    t        |       }t        |t              S r<   )rr   rm   _RECOVERABLE_STREAM_EXCEPTIONSrq   wrappeds     r8   _should_recoverr{          #I.Gg=>>r:   c                 8    t        |       }t        |t              S r<   )rr   rm   _TERMINATING_STREAM_EXCEPTIONSry   s     r8   _should_terminater      r|   r:   c            
       6   e Zd Zd Zd Zed        Zed        Zd Zd Z	e
d        Zdd	Zd
 Zd Zd Zd Zd Zd Zd Zej*                  eej,                  eej.                  eej0                  eej2                  eiZd Zd Zd Zed        Zd Z d Z!d Z"y)Watchc                 t   || _         || _        || _        || _        || _        || _        |j                  | _        t        j                         | _
        d| _        | j                  |j                         d| _        t               | _        i | _        i | _        d| _        d| _        | j+                          y)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)_document_reference
_firestore_targets_comparator_document_snapshot_cls_snapshot_callback_firestore_api_api	threadingLock_closing_closed_set_documents_pfx_database_stringresume_tokenr2   doc_treedoc_map
change_mapcurrent
has_pushed_init_stream)r7   document_reference	firestoretarget
comparatorsnapshot_callbackdocument_snapshot_clss          r8   r9   zWatch.__init__   s    4 $6 #%&;#"3,,	!(	 : :; 
 %   
  r:   c                    | j                   }t        | j                  j                  j                  t
        t        || j                  j                        | _	        | j                  j                  | j                         t        | j                  | j                        | _        | j                  j                          y )N)	start_rpcshould_recovershould_terminateinitial_requestmetadata)_get_rpc_requestr   r   
_transportlistenr{   r   r   _rpc_metadata_rpcadd_done_callback_on_rpc_doner   on_snapshot	_consumerstart)r7   rpc_requests     r8   r   zWatch._init_stream   s    ++$ii**11*.'__22
	 			##D$5$56 ,DIIt7G7GHr:   c                 `     | ||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_id)_client_document_pathWATCH_TARGET_IDrv   )clsdocument_refr   r   s       r8   for_documentzWatch.for_document   sA    &   )L,G,G+HI, &!

 
	
r:   c                     |j                   j                         \  }}t        j                  ||j	                               } | ||j
                  |j                  t        d|j                  ||      S )N)parentstructured_query)queryr   )	_parent_parent_infor	   QueryTarget_to_protobufr   _pbr   r   )r   r   r   r   parent_path_query_targets          r8   	for_queryzWatch.for_query  sl    335Q))1C1C1E
 MM"&&_E!
 	
r:   c                     | j                   | j                   | j                  d<   n| j                  j                  dd        t        | j                  j
                  | j                        S )Nr   )database
add_target)r   r   popr   r   r   r6   s    r8   r   zWatch._get_rpc_request(  sV    (,0,=,=DMM.)MMnd3__55$--
 	
r:   c                 L    | d| _         t        | j                         | _        y )Nz/documents/)_documents_pfxrQ   _documents_pfx_len)r7   database_strings     r8   r   zWatch._set_documents_pfx2  s%    !0 1="%d&9&9":r:   c                 N    | j                   duxr | j                   j                  S )zbool: 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_activer6   s    r8   r   zWatch.is_active6  s"     ~~T)Fdnn.F.FFr:   Nc                 R   | j                   5  | j                  r
	 ddd       y| j                  r/t        j	                  d       | j
                  j                          d| j
                  _        d| _        d| _        | j                  j                          d| j                  _        g | j                  _        d| _	        d| _        t        j	                  d       ddd       |r5t        j	                  d|z         t        |t              r|t        |      y# 1 sw Y   AxY w)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)r   r   r   _LOGGERdebugr   stop_on_responser   r   close_initial_request
_callbacksrm   	ExceptionRuntimeError)r7   reasons     r8   r   zWatch.close?  s     ]] 	8||	8 	8
 ~~23##%*.DNN'!DN&*D#IIOO)-DII&#%DII DIDLMM67#	8& MM2V;<&),v&& '	8 	8s   DB9DD&c                     t         j                  d       t        |      }t        j                  t
        | j                  d|i      }d|_        |j                          y)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   )rj   r   kwargsTN)	r   inforr   r   Thread_RPC_ERROR_THREAD_NAMEr   daemonr   )r7   futurethreads      r8   r   zWatch._on_rpc_doneb  sM     	EF&v.!!'

HfCU
 r:   c                 $    | j                          y r<   )r   r6   s    r8   unsubscribezWatch.unsubscribeu  s    

r:   c                    t         j                  d       |j                  d u xs t        |j                        dk(  }|rA|j                  r4| j
                  r'| j                  |j                  |j                         y y y y )Nz%on_snapshot: target change: NO_CHANGEr   )r   r   
target_idsrQ   	read_timer   pushr   )r7   target_changeno_target_idss      r8   $_on_snapshot_target_change_no_changez*Watch._on_snapshot_target_change_no_changex  st    => $$,RM4L4L0MQR0R 	 ]44
 IIm--}/I/IJ :F4=r:   c                 z    t         j                  d       |j                  d   }|t        k7  rt	        d|z        y )Nzon_snapshot: target change: ADDr   z&Unexpected target ID %s sent by server)r   r   r   r   r   )r7   r   r   s      r8   _on_snapshot_target_change_addz$Watch._on_snapshot_target_change_add  s=    78!,,Q/	'G)STT (r:   c                 
   t         j                  d       |j                  j                  r-|j                  j                  }|j                  j                  }nd}d}d|d|}t        |      t        j                  ||      )Nz"on_snapshot: target change: REMOVEr'   zinternal errorzError z:  )r   r   causecodemessager   r   from_grpc_status)r7   r   r   r   error_messages        r8   !_on_snapshot_target_change_removez'Watch._on_snapshot_target_change_remove  st    :;## &&++D#))11GD&G+/9=)z/J/J'0
 	
r:   c                 N    t         j                  d       | j                          y )Nz!on_snapshot: target change: RESET)r   r   _reset_docsr7   r   s     r8    _on_snapshot_target_change_resetz&Watch._on_snapshot_target_change_reset  s    9:r:   c                 <    t         j                  d       d| _        y )Nz#on_snapshot: target change: CURRENTT)r   r   r   r   s     r8   "_on_snapshot_target_change_currentz(Watch._on_snapshot_target_change_current  s    ;<r:   c                 Z    |j                  | j                        r|| j                  d  }|S r<   )
startswithr   r   )r7   document_names     r8   _strip_document_pfxzWatch._strip_document_pfx  s/    ##D$7$78)$*A*A*CDMr:   c                    | j                   j                         ry|| j                          y|j                  }|j	                  d      }|dk(  r|j
                  j                  }t        j                  d|        | j                  j                  |      }|8d| }t        j                  d|        | j                  t        |             	  || |j
                         y|d	k(  r_t        j                  d
       t        |j                  j                   v }t        |j                  j"                  v }	|j                  j$                  }
|rt        j                  d       t'        j(                  |
j*                  | j,                        }| j/                  |
j0                        }| j,                  j%                  |      }| j3                  ||dd|
j4                  |
j6                        }|| j8                  |
j0                  <   y|	r=t        j                  d       t:        j<                  | j8                  |
j0                  <   yy|dk(  rIt        j                  d       |j>                  j$                  }t:        j<                  | j8                  |<   y|dk(  rIt        j                  d       |j@                  j$                  }t:        j<                  | j8                  |<   y|dk(  rt        j                  d       |jB                  jD                  | jG                         k7  r{t        j                  d       tI        jJ                  tL        | j                        }|jO                          |jQ                          | jS                          | jU                          yyt        j                  d       d| }| j                  t        |             y# t        $ r}t        j                  d|         d}~ww xY w)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
        N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.)rj   r   zUNKNOWN TYPE. UHOHzUnknown listen response type: )+r   lockedr   r   
WhichOneofr   target_change_typer   r   _target_changetype_dispatchgetr   
ValueErrorr   r   r   r   removed_target_idsrb   r   decode_dictfieldsr   r   rj   r   r  r  r   rZ   r\   r  r  r  count_current_sizer   r   r   r   joinr   r   )r7   protopbwhichr  methr   exc2changedremovedrb   r  r   r   ri   rj   r   s                    r8   r   zWatch.on_snapshot  sK    ==!=JJLYYo.O#!#!1!1!D!DMM89K8LMN33778JKD|89K8LM}WI67

*W"5
6T5../ ''MM89 &););)F)FFG%););)N)NNG ,,55HEF++HOOT__M
 !% 8 8 G#77F66*" ( 4 4 ( 4 4 7  2:.EF1;1C1C.  ''MM@A%%..D$.$6$6DOOD!''MM@A%%..D$.$6$6DOOD!hMM67yy$"4"4"66DE"))/::   "!!# 7 MM./6ug>GJJj1J2[   1$89s   O 	P&O??Pc                    | j                  | j                  | j                  |      \  }}}| j                  | j                  | j                  |||      \  }}}| j
                  rt        |      rTt        j                  | j                        }	t        |j                         |	      }
| j                  |
||       d| _        || _        || _        | j                  j                          || _        y)zInvoke the callback with a new snapshot

        Build the sntapshot from the current set of changes.

        Clear the current changes on completion.
        rD   TN)_extract_changesr   r   _compute_snapshotr   r   rQ   	functools
cmp_to_keyr   sortedr>   r   clearr   )r7   r   next_resume_tokendeletesaddsupdatesupdated_treeupdated_mapappliedChangesrD   r>   s              r8   r   z
Watch.push"  s     "&!6!6LL$//9"
w 594J4JMM4<<$5
1k> #n"5 &&t'7'78C,++-37D##D.)D"DO$"-r:   c                    g }g }g }|j                         D ]h  \  }}|t        j                  k(  r|| v s|j                  |       0|| v r|||_        |j                  |       O|||_        |j                  |       j |||fS r<   )itemsrZ   r\   appendr   )r   changesr   r%  r&  r'  rj   r/   s           r8   r  zWatch._extract_changes?  s    "==? 	#KD%
***7?NN4((&/EOu%(&/EOE"	# w''r:   c                 r   |}|}t        |      t        |      k(  sJ d       d d fd}g }	t        j                  | j                        }
t	        |      }|D ]!  } |||      \  }}}|	j                  |       # t	        ||
      }t        j                  d       |D ]6  }t        j                  d        |||      \  }}}|	j                  |       8 t	        ||
      }|D ]$  } ||||      \  }}}||	j                  |       & t        |      t        |      k(  sJ d       |||	fS )	NzJThe document tree and document map should have the same number of entries.c                     | |v sJ d       |j                  |       }|j                  |      }|j                  }|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-   )r  rI   r0   rK   r_   rZ   r\   )rj   r(  r)  old_documentexistingrc   s         r8   
delete_docz+Watch._compute_snapshot.<locals>.delete_doc_  s{    
 ;&K(KK&&??40L#((6H I'..|<LD!z11<BO r:   c                     | j                   j                  }||vsJ d       |j                  | d      }|j                  |       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   rE   rI   r0   r_   rZ   r[   )new_documentr(  r)  rj   rd   s        r8   add_docz(Watch._compute_snapshot.<locals>.add_docq  s    
  ))88D{*L,LL*'..|TBL$)),7==I ,Kz//r9M r:   c                 B   | j                   j                  }||v sJ d       |j                  |      }|j                  | j                  k7  rO |||      \  }}} | ||      \  }}}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  r_   rZ   r]   rc   rd   )	r5  r(  r)  rj   r1  remove_change
add_changer6  r3  s	          r8   
modify_docz+Watch._compute_snapshot.<locals>.modify_doc  s      ))88D;&K(KK&&??40L''<+C+CC;E,<8|[ 9@ ,95
L+ #"++$%//",,	 !	 	 {22r:   r  zwalk over add_changeszin add_changeszQThe update document tree and document map should have the same number of entries.)rQ   r   r!  r   r"  r-  r   r   )r7   r   r   delete_changesadd_changesupdate_changesr(  r)  r:  r*  rD   rj   changeri   r6  r3  s                 @@r8   r  zWatch._compute_snapshotT  s     8}G, 	
#	
,
	$	 	3B ""4#3#34  /" 	*D0:lK1-FL+ !!&)		* [c2-.# 	*HMM*+07,1-FL+ !!&)	*  C8& 	.H0:,1-FL+ !%%f-	. < C$44 	
6	
4 k>::r:   c                     | j                  | j                  | j                  d      \  }}}t        | j                        t        |      z   t        |      z
  S )zsReturn the current count of all documents.

        Count includes the changes from the current changeMap.
        N)r  r   r   rQ   )r7   r%  r&  r   s       r8   r  zWatch._current_size  sI    
  00tPTUq4<< 3t9,s7|;;r:   c                 "   t         j                  d       | j                  j                          d| _        | j
                  j                         D ]5  }|j                  j                  }t        j                  | j                  |<   7 d| _        y)zG
        Helper to clear the docs on RESET or filter mismatch.
        zresetting documentsNF)r   r   r   r#  r   r   r>   r  r   rZ   r\   r   )r7   ri   rj   s      r8   r   zWatch._reset_docs  su     	+,  **, 	7H%%44D$.$6$6DOOD!	7 r:   r<   )#rU   rV   rW   r9   r   classmethodr   r   r   r   propertyr   r   r   r   r   r   r   r   r   TargetChangeType	NO_CHANGEADDREMOVERESETCURRENTr  r   r   r   staticmethodr  r  r  r   rX   r:   r8   r   r      s    <|" 
 
< 
 

; G G!'F&KU
 

 	""$H<!B @  "D#
o3b.: ( ((o;b<r:   r   )/collectionsr   loggingr   enumr   rn   google.api_corer   google.api_core.bidir   r   google.cloud.firestore_v1r   )google.cloud.firestore_v1.types.firestorer   r	   r
   rC  	getLoggerrU   r   r   GRPC_STATUS_CODEr   Aborted	CancelledUnknownDeadlineExceededResourceExhaustedInternalServerErrorServiceUnavailableUnauthenticatedrx   r~   
namedtupler.   objectr2   rZ   r_   rg   rr   rv   r{   r   r   rX   r:   r8   <module>r]     s         & E .   00 
'

H
%! q 	
   a  r ! 1 r B R   2!" #$ "% ( 2   ""!!	"  #-"6"6!8 %{%%nw6HI(6 (V #V #"'& '
?
?
rF rr:   