
    ;Six                     v   d 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m	Z	 ddl
mZ
mZ ddlmZ dZd	Zd
ZdZdZ G d d      Z ed      Z ed      Zej0                  ej2                  z
  dz  Z e       Zd Zd Z G d de      Z G d de      Z  G d d      Z! G d d      Z" G d d      Z# G d d      Z$y)a  
This module deals with correct handling of updates, including gaps, and knowing when the code
should "get difference" (the set of updates that the client should know by now minus the set
of updates that it actually knows).

Each chat has its own [`Entry`] in the [`MessageBox`] (this `struct` is the "entry point").
At any given time, the message box may be either getting difference for them (entry is in
[`MessageBox::getting_diff_for`]) or not. If not getting difference, a possible gap may be
found for the updates (entry is in [`MessageBox::possible_gaps`]). Otherwise, the entry is
on its happy path.

Gaps are cleared when they are either resolved on their own (by waiting for a short time)
or because we got the difference for the corresponding entry.

While there are entries for which their difference must be fetched,
[`MessageBox::check_deadlines`] will always return [`Instant::now`], since "now" is the time
to get the difference.
    N)Enum   )SessionStateChannelState   )types	functions)get_running_loopi d   g      ?i  c                       e Zd ZdZddZd Zy)SentineltagNc                     |xs d| _         y )N_r   )selfr   s     a/var/www/OnlineNewsSite/project/venv/lib/python3.12/site-packages/telethon/_updates/messagebox.py__init__zSentinel.__init__4   s    :#    c                     | j                   S Nr   r   s    r   __repr__zSentinel.__repr__7   s    xxr   r   )__name__
__module____qualname__	__slots__r   r    r   r   r   r   1   s    Ir   r   ACCOUNTSECRETc                  @    t               j                         t        z   S r   )r
   timeNO_UPDATES_TIMEOUTr   r   r   next_updates_deadliner$   G   s    ""$'999r   c                      t        j                   t        j                  d      d d  j                  t         j                  j
                        S )Nr      )tzinfo)datetimer"   gmtimereplacetimezoneutcr   r   r   epochr-   J   s<    dkk!nRa0199ARARAVAV9WWr   c                       e Zd Zd Zy)GapErrorc                      y)Nz
GapError()r   r   s    r   r   zGapError.__repr__N   s    r   N)r   r   r   r   r   r   r   r/   r/   M   s    r   r/   c                       e Zd ZdZdZy)PrematureEndReasontmpbanN)r   r   r   TEMPORARY_SERVER_ISSUESBANNEDr   r   r   r2   r2   R   s    #Fr   r2   c                   :    e Zd ZdZdededefdZed        Zd Z	y)	PtsInfopts	pts_countentryr:   r;   r<   c                 .    || _         || _        || _        y r   r9   )r   r:   r;   r<   s       r   r   zPtsInfo.__init__[   s     "
r   c                     t        |dd       }|r=t        |dd       xs d}	 |j                  j                  j                  } | |||      S t        |dd       }|r | |dt              S y # t        $ r t        |dd       xs t
        }Y Jw xY w)Nr:   r;   r   
channel_idr9   qtsr   )getattrmessagepeer_idr?   AttributeErrorENTRY_ACCOUNTENTRY_SECRET)clsupdater:   r;   r<   r@   s         r   from_updatezPtsInfo.from_updatee   s    feT*T:?aIM..99 3)5AAfeT*3!<@@ " Md;L}Ms    A, ,BBc                 V    d| j                    d| j                   d| j                   dS )NzPtsInfo(pts=z, pts_count=z, entry=)r9   r   s    r   r   zPtsInfo.__repr__v   s+    dhhZ|DNN3C8DJJ<WXYYr   N)
r   r   r   r   intobjectr   classmethodrI   r   r   r   r   r8   r8   X   sB    -I  	   Zr   r8   c                   &    e Zd ZdZdedefdZd Zy)Stater:   deadliner:   rR   c                      || _         || _        y r   rQ   )r   r:   rR   s      r   r   zState.__init__~   s      r   c                 <    d| j                    d| j                   dS )Nz
State(pts=z, deadline=rK   rQ   r   s    r   r   zState.__repr__   s    DHH:[qAAr   N)r   r   r   r   rL   floatr   r   r   r   r   rP   rP   {   s&    #I! !
 !Br   rP   c                   &    e Zd ZdZdedefdZd Zy)PossibleGaprR   updatesrR   rY   c                      || _         || _        y r   rX   )r   rR   rY   s      r   r   zPossibleGap.__init__   s     !r   c                 N    d| j                    dt        | j                         dS )NzPossibleGap(deadline=z, update_count=rK   )rR   lenrY   r   s    r   r   zPossibleGap.__repr__   s&    &t}}o_SEVDWWXYYr   N)r   r   r   r   rU   listr   r   r   r   r   rW   rW      s$    'I 	Zr   rW   c                   
   e Zd ZdZe e        ej                  d      z   edeefde	dej                  de
ded	e	d
efdZd Zd Zd ZdefdZd Zd Zd Zd"dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d e"fd!Z#y)#
MessageBox)_logmapdateseqnext_deadlinepossible_gapsgetting_diff_forr   )secondsNra   rb   rc   rd   re   rf   c                     || _         |t        u ri n|| _        || _        || _        || _        |t        u ri n|| _        |t        u r
t               n|| _        	 | j                  d       y )NzMessageBox initialized)
r`   	_sentinelra   rb   rc   rd   re   setrf   _trace)r   logra   rb   rc   rd   re   rf   s           r   r   zMessageBox.__init__   sf    2 		)2s	*#0I#=R=)9Y)FL\KK01r   c                     | j                   j                  t        d| j                  | j                  j                         | j                          | j                   j                  t        |g|i | y )Nz7Current MessageBox state: seq = %r, date = %s, map = %r)r`   rl   LOG_LEVEL_TRACErc   rb   	isoformatra   )r   msgargskwargss       r   rk   zMessageBox._trace   sT    
 			o'`hh		 3 3 5txx	A		os<T<V<r   c                 r   	 | j                  d||       t               | j                  j                          |j                  t
        k7  r(t        |j                        | j                  t        <   |j                  t
        k7  r(t        |j                        | j                  t        <   | j                  j                  fd|D               t        j                  j                  |j                  t        j                  j                        | _        |j                   | _        t        | _        y)zO
        Create a [`MessageBox`] from a previously known update state.
        z?Loading MessageBox with session_state = %r, channel_states = %rrQ   c              3   d   K   | ]'  }|j                   t        |j                         f ) yw)rQ   N)r?   rP   r:   ).0srR   s     r   	<genexpr>z"MessageBox.load.<locals>.<genexpr>   s&     dPQu'JKds   -0)tzN)rk   r$   ra   clearr:   NO_SEQrP   rE   r@   rF   rH   r(   fromtimestamprb   r+   r,   rc   rd   )r   session_statechannel_statesrR   s      @r   loadzMessageBox.load   s     KKY[hjxy(*&&+0A0AH&UDHH]#&%*}/@/@8%TDHH\"dUcdd%%33M4F4F8K\K\K`K`3a	 $$*r   c           	         t        t        | j                  v r| j                  t           j                  nt        t
        | j                  v r| j                  t
           j                  nt        | j                  | j                        | j                  j                         D ci c]#  \  }}t        |t              s||j                  % c}}fS c c}}w )zb
        Return the current state.

        This should be used for persisting the state.
        )r:   r@   rb   rc   )dictrE   ra   r:   rz   rF   rb   rc   items
isinstancerL   )r   idstates      r   r|   zMessageBox.session_state   s     /</H'++f.:dhh.F&**F	

 ,088>>+;Sib%z"c?RB		MST 	T
 Ts   &C?Creturnc                 &    t         | j                  vS )zO
        Return true if the message box is empty and has no state yet.
        )rE   ra   r   s    r   is_emptyzMessageBox.is_empty   s     DHH,,r   c                    t               j                         | j                  rS t               }| j                  r,t        |gd | j                  j                         D         }nE| j                  | j                  v r-t        || j                  | j                     j                        }|k\  r| j                  j                  fd| j                  j                         D               | j                  j                  fd| j                  j                         D               	 | j                  d| j                         | j                  D ]  }| j                  j                  |d         |S )a*  
        Return the next deadline when receiving updates should timeout.

        If a deadline expired, the corresponding entries will be marked as needing to get its difference.
        While there are entries pending of getting their difference, this method returns the current instant.
        c              3   4   K   | ]  }|j                     y wr   rR   )ru   gaps     r   rw   z-MessageBox.check_deadlines.<locals>.<genexpr>  s     &[s||&[s   c              3   H   K   | ]  \  }}|j                   k\  s|  y wr   r   )ru   r<   r   nows      r   rw   z-MessageBox.check_deadlines.<locals>.<genexpr>  s$     (s:5#_bfifrfr_r(s   ""c              3   H   K   | ]  \  }}|j                   k\  s|  y wr   r   )ru   r<   r   r   s      r   rw   z-MessageBox.check_deadlines.<locals>.<genexpr>  s$     (m<5%WZ^c^l^lWl(mr   z&Deadlines met, now getting diff for %rN)r
   r"   rf   r$   re   minvaluesrd   ra   rR   rH   r   rk   pop)r   rR   r<   r   s      @r   check_deadlineszMessageBox.check_deadlines   s1     %%'  J(* 8\&[t?Q?Q?X?X?Z&[\H488+8TXXd.@.@%A%J%JKH
 (?!!(((sASASAYAYA[(ss!!(((m488>>CS(mmDdF[F[\ .. 4""&&ud34 r   c                 z   |sy |D ]/  }|| j                   vrt        d      || j                   |   _        1 | j                  |v r/t	        | j                   j                         d       d   | _        y | j                  | j                   v r/|| j                   | j                     j                  k  r| _        y y y )Nz@Called reset_deadline on an entry for which we do not have statec                      | d   j                   S )Nr   r   )entry_states    r   <lambda>z,MessageBox.reset_deadlines.<locals>.<lambda>3  s    {[\~OfOf r   keyr   )ra   RuntimeErrorrR   rd   r   r   )r   entriesrR   r<   s       r   reset_deadlineszMessageBox.reset_deadlines)  s     	0EDHH$"#eff'/DHHUO$	0
 (!$TXX^^%5;f!ghi!jD488+488DDVDV;W;`;`0` "'D 1a+r   c                 l    | j                  |ht               j                         |xs t        z          y r   )r   r
   r"   r#   )r   r?   timeouts      r   reset_channel_deadlinez!MessageBox.reset_channel_deadline;  s,    j\+;+=+B+B+DHeSe+fgr   c                    	 | j                  d|       t               }|j                  t        k7  s|s)t	        |j                  |      | j
                  t        <   n | j
                  j                  t        d        |j                  t        k7  s|s)t	        |j                  |      | j
                  t        <   n | j
                  j                  t        d        |j                  | _
        |j                  | _        y )NzSetting state %srQ   )rk   r$   r:   rz   rP   ra   rE   r   r@   rF   rb   rc   )r   r   resetrR   s       r   	set_statezMessageBox.set_stateB  s    KK*E2(*99e&+		H&MDHH]#HHLL- 99e%*uyy8%LDHH\"HHLLt,JJ	99r   c                     	 | j                  d||       || j                  vr#t        |t                     | j                  |<   y y )Nz&Trying to set channel state for %r: %rrQ   )rk   ra   rP   r$   )r   r   r:   s      r   try_set_channel_statez MessageBox.try_set_channel_state_  s?    KK@"cJTXX S3H3JKDHHRL r   c                    || j                   vr.|| j                  v rt        d      	 | j                  d||       y 	 | j                  d||       | j                  j                  |       | j                  j                  |d        y )Nz@Should not have a possible_gap for an entry not in the state mapzFShould get difference for %r because %s but cannot due to missing hashz+Marking %r as needing difference because %s)ra   re   r   rk   rf   addr   )r   r<   reasons      r   try_begin_get_diffzMessageBox.try_begin_get_diffj  s     ***"#effdfkmstKKEufU!!%(ud+r   c                     	 | j                   j                  |       | j	                  |ht                      || j                  vsJ d       y # t        $ r t        d      w xY w)Nz>Called end_get_diff on an entry which was not getting diff forz2gaps shouldn't be created while getting difference)rf   removeKeyErrorr   r   r$   re   )r   r<   s     r   end_get_diffzMessageBox.end_get_diff|  sm    	a!!((/ 	eW&;&=>D...d0dd.	  	a_``	as   A A#c           
          t        |dd      }|}g }t        |dd       }t        |dd       }t        |dd       }t        |dd       xs g }	t        |dd       xs g }
	  j                  d|||r|j                         nd |       | j                  t        d	       t
        |t        }||}t        |d
d       xs) t        |t        j                        r|j                  n|g}|D ]	  }||_         |t        k7  rV j                  dz   |kD  r	  j                  d       |	|
fS  j                  dz   |k  r j                  t        d       t
        d }t               |j                  t        d  fdt!        ||      D                      j#                  t%                       j&                  r]	  j                  dt)         j&                               t+         j&                  j-                               D ]  } j&                  |   j.                  j1                  |       t3        t)         j&                  |   j.                              D ]x  } j&                  |   j.                  j5                  d      } j7                  |d       }|sA|j9                  |       	  j                  dt:        j=                  |      |       z   j&                  j?                         D ci c]  \  }}|j.                  s|| c}} _        |j                  d |D               |rB j&                  s6	  j                  d       |tA               k7  r| _!        |t        k7  r| _        |	|
fS c c}}w )N_self_outgoingFrb   rc   	seq_startuserschatsz?Processing updates with seq = %r, seq_start = %r, date = %s: %szreceived updatesTooLongrY   r   z9Skipping updates as they should have already been handledzdetected gapc                 f    t         j                  |       }|r|j                  |j                  z
  S dS )Nr   )r8   rI   r:   r;   )rH   r:   s     r   
_sort_gapsz.MessageBox.process_updates.<locals>._sort_gaps  s,    %%f-C.1377S]]*8q8r   c              3   D   K   | ]  }j                  |         yw)r   N)apply_pts_info)ru   ur   r   s     r   rw   z-MessageBox.process_updates.<locals>.<genexpr>  s+      $6
 	 ?C$6s    r   z#Trying to re-apply %r possible gapsr   r   zResolved gap with %r: %sc              3   :   K   | ]  }|j                   r|  y wr   )r   )ru   r   s     r   rw   z-MessageBox.process_updates.<locals>.<genexpr>  s     EA4D4D1Es   z(Updating seq as all updates were applied)"rA   rk   ro   r   rE   r/   rz   r   tlUpdateShortrH   r   rc   rj   extendfiltersortedr   r$   re   r\   r]   keysrY   sortranger   r   appendr8   rI   r   r-   rb   )r   rY   chat_hashesresultself_outgoingreal_resultrb   rc   r   r   r   r   r   r   r   rH   r<   r   r   s   `                 @r   process_updateszMessageBox.process_updates  sO     )95Aw-gud+G[$7	$/52$/52KKYYD(8dGU <##M3LMN;CI '9d3{*U\^`^l^lJmsz7{ 	-A,A	-
 xx!|i'KK [\u~%A	)''~F	9 %fT $6
 G4$6 7 	8 	_.C.EFA3tGYGYCZ[ D..3356 i""3'//444Ds4#5#5c#:#B#BCD 	iA!//4<<@@CF "000NFf-$ KK(BGDWDWX^D_agh	ii @D?Q?Q?W?W?Y!i]`]h]h%*!iDEfEE$,, FGuw 	f}u~ "js   2M5M5c                   t        |t        j                        r| j                  |j                  d       y t
        j                  |      }|s	 | j                  d|       |S |r|j                  |j                         |j                  | j                  v r	 | j                  d|       y |j                  | j                  v r'| j                  |j                     j                  }||j                  z   |j                  kD  r	 | j                  d|||       y ||j                  z   |j                  k  r	 | j                  d|||       |j                  | j                  vrAt        t!               j#                         t$        z   g       | j                  |j                  <   | j                  |j                     j&                  j)                  |       y 	 | j                  d|||       |j                  | j                  v r*|j                  | j                  |j                     _        |S t+        |j                  |j                  rdnd	z
  xs d	t-               
      | j                  |j                  <   |S )Nzreceived updateChannelTooLongz7No pts in update, so it can be applied in any order: %sz:Skipping update with %r as its difference is being fetchedz+Skipping update since local pts %r > %r: %sz(Possible gap since local pts %r < %r: %srX   z/Applying update pts since local pts %r = %r: %sr   r   rQ   )r   r   UpdateChannelTooLongr   r?   r8   rI   rk   r   r<   rf   ra   r:   r;   re   rW   r
   r"   POSSIBLE_GAP_TIMEOUTrY   r   rP   r$   )r   rH   r   r:   	local_ptss        r   r   zMessageBox.apply_pts_info  s    fb556##F$5$57VW!!&)UW]^M 		*99--- XZ]^99 +//I3==(3772KK MyZ]_efS]]*SWW4 KK JIWZ\bc99D$6$664?!1!3!8!8!:=Q!Q "5D&&syy1
 ""399-55<<VD KK QS\^acij  99 &)ggDHHSYY#  #(WWS]]:@q.0#DHHSYY
 r   c                    t         t        fD ]  }|| j                  v s|| j                  vrt	        d      t
        j                  j                  | j                  t            j                  d | j                  t        | j                  v r| j                  t           j                  nt              }	 | j                  d|       |c S  y )NAShould not try to get difference for an entry without known state)r:   pts_total_limitrb   r@   z Requesting account difference %s)rE   rF   rf   ra   r   fnrY   GetDifferenceRequestr:   rb   rz   rk   )r   r<   gds      r   get_differencezMessageBox.get_difference`  s    #\2 	E---(&'jkkZZ44/33$(6Bdhh6N.22TZ	 5  KK BBG		 r   c                    	 | j                  d|       d }d }t        |t        j                  j                        r+d}|j
                  | _        |j                  | _        g g g f}nt        |t        j                  j                        r;d}|j                  |j                  |j                         | j                  ||      }nt        |t        j                  j                        r;d}|j                  |j                  |j                         | j                  ||      }nMt        |t        j                  j                        r)d}|j                  | j                  t            _        g g g f}|rat         | j"                  v }t$        | j"                  v }|s|st'        d      |r| j)                  t                |r| j)                  t$               |S )NTzApplying account difference %sFzXShould not be applying the difference when neither account or secret was diff was active)rk   r   r   rY   DifferenceEmptyrb   rc   
Differencer   r   r   apply_difference_typeDifferenceSliceDifferenceTooLongr:   ra   rE   rf   rF   r   r   )r   diffr   finishr   accountsecrets          r   apply_differencezMessageBox.apply_differences  sv   
 KK8$?dBJJ667F		DIxxDHRZFbjj334Ftzz4::6//kBFbjj889Ftzz4::6//kBFbjj::;F*.((DHH]#'RZF#t'<'<<G!T%:%::F6"#}~~ !!-0!!,/r   c           	         t        |dd       xs |j                  }| j                  |d       g }| j                  t	        j
                  |j                  |j                  |j                  t               t              ||       |j                  d |j                  D               |j                  d |j                  D               ||j                  |j                  fS )Nintermediate_stateF)r   rY   r   r   rb   rc   c              3   \   K   | ]$  }t        j                  |t        t                & yw)rB   r:   r;   N)r   UpdateNewMessagerz   ru   ms     r   rw   z3MessageBox.apply_difference_type.<locals>.<genexpr>  s3      & 	 **
 
 &   *,c              3   R   K   | ]  }t        j                  |t                ! yw))rB   r@   N)r   UpdateNewEncryptedMessagerz   r   s     r   rw   z3MessageBox.apply_difference_type.<locals>.<genexpr>  s0      0  33
 
 0s   %')rA   r   r   r   r   Updatesother_updatesr   r   r-   rz   r   new_messagesnew_encrypted_messages)r   r   r   r   rY   s        r   r   z MessageBox.apply_difference_type  s    
 2D9GTZZuE* RZZ&&****
 	! 	 & $$	& 	&
 	 0 ..0 	0
 

DJJ..r   c                     	 | j                  d       t        | j                  v }t        | j                  v }|s|st	        d      |r| j                  t               |r| j                  t               y y )NzEnding account differencezVShould not be ending get difference when neither account or secret was diff was active)rk   rE   rf   rF   r   r   )r   r   r   s      r   end_differencezMessageBox.end_difference  sl    KK344#8#88!6!66vwxx m,l+ r   c                 :   t        d | j                  D        d       }|sy |j                  |      }|s.| j                  |       | j                  j                  |d        y | j                  j                  |      }|st        d      t        j                  j                  dt        j                  |j                  |j                        t        j                         |j                  |j                   rt"        nt$              }	 | j'                  d|       |S )Nc              3   B   K   | ]  }t        |t              s|  y wr   )r   rL   )ru   r   s     r   rw   z4MessageBox.get_channel_difference.<locals>.<genexpr>  s     PRJr3<ObPs   r   F)forcechannelr   r:   limitz Requesting channel difference %s)nextrf   getr   ra   r   r   r   rY   GetChannelDifferenceRequestr   InputChannelr   hashChannelMessagesFilterEmptyr:   self_botBOT_CHANNEL_DIFF_LIMITUSER_CHANNEL_DIFF_LIMITrk   )r   r   r<   packedr   r   s         r   get_channel_differencez!MessageBox.get_channel_difference  s     P4#8#8PRVW' e$ HHLL%U#bccZZ33OOFIIv{{;002		,7,@,@(F] 4 
 KK:B?	r   c           	         |j                   j                  }	 | j                  d||       | j                  j	                  |d        t        |t        j                  j                        rB|j                  sJ | j                  |       |j                  | j                  |   _        g g g fS t        |t        j                  j                        r}|j                  sJ |j                  j                  | j                  |   _        |j                  |j                   |j"                         | j%                  ||j&                         g g g fS t        |t        j                  j(                        r|j                  r| j                  |       |j                  | j                  |   _        |j                  |j                   |j"                         g }| j+                  t        j,                  |j.                  |j                   |j"                  t1               t2              ||       |j                  d |j4                  D               | j%                  |d        ||j                   |j"                  fS y )Nz&Applying channel difference for %r: %sr   c              3   \   K   | ]$  }t        j                  |t        t                & ywr   )r   UpdateNewChannelMessagerz   r   s     r   rw   z6MessageBox.apply_channel_difference.<locals>.<genexpr>  s3      * 	 55   *r   )r   r?   rk   re   r   r   r   rY   ChannelDifferenceEmptyfinalr   r:   ra   ChannelDifferenceTooLongdialogr   r   r   r   r   ChannelDifferencer   r   r   r-   rz   r   )r   requestr   r   r<   rY   s         r   apply_channel_differencez#MessageBox.apply_channel_difference  s    **KK@%Nud+dBJJ==>:::e$"&((DHHUOr2:bjjAAB:::"&++//DHHUOtzz4::6''t||< r2:bjj::;zz!!%("&((DHHUOtzz4::6G  **jjjjW" G% NN * ((	* *
 ''t4DJJ

22/ <r   r   c                    |j                   j                  }	 | j                  d||       |t        j                  k(  r.| j
                  j                  |d        | j                  |       y |t        j                  k(  r;| j
                  j                  |d        | j                  |       | j                  |= y t        d      )Nz+Ending channel difference for %r because %sz(Unknown reason to end channel difference)r   r?   rk   r2   r5   re   r   r   r6   ra   r   )r   r  r   r   r<   s        r   end_channel_differencez!MessageBox.end_channel_difference(  s    **KKEufU'???""5$/e$)000""5$/e$IJJr   )T)$r   r   r   r   ri   r-   r(   	timedeltarz   r   rL   rM   rj   r   rk   r~   r|   boolr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r2   r	  r   r   r   r_   r_      s   dI  #(',>H,>,>q,I"I !% ( !*/"2 	"2 "2 "2 "2( )"2. /"2H=+(T-$ -$R'$h:L,$e2fZW|&*X/>,*D13fK6H Kr   r_   )%__doc__asyncior(   r"   loggingenumr   sessionr   r   r   r   r	   r   helpersr
   rz   r   r   r   r#   r   rE   rF   DEBUGNOTSETrn   ri   r$   r-   
ValueErrorr/   r2   r8   rP   rW   r_   r   r   r   <module>r     s   $      / - & 
          #!
 ==7>>1a7J	:Xz 
 Z ZFB B2Z Z&P
K P
Kr   