o
    Fhc                     @  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mZmZm	Z	 d dl
mZ d dlmZmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lm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dl%m&Z&m'Z' ddl(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? e4dddddZ@G dd  d e?ZAdS )!    )annotationsN)CancelledErrorEventFutureLock)suppress)AnyAsyncGenerator	AwaitableDictListOptionalSetUnion   )loggers)Bot)TelegramAPIError)FSMContextMiddleware)BaseEventIsolationBaseStorage)DisabledEventIsolationMemoryStorage)FSMStrategy)
GetUpdatesTelegramMethod)TelegramType)UpdateUser)UNSET
UNSET_TYPE)UpdateTypeLookupError)BackoffBackoffConfig   )	UNHANDLEDSkipHandler)TelegramEventObserver)ErrorsMiddleware)UserContextMiddleware)Routerg      ?g      @g?g?)	min_delay	max_delayfactorjitterc                      s\  e Zd ZdZdejdddddl fddZdmddZdnddZdoddZ	dpdqd!d"Z
edrd$d%Zedsd'd(Zejdtd*d(Zdud/d0Zdvd2d3Zed4edfdwd<d=Zdxd>d?ZedydBdCZ	Ddzd{dFdGZd|dLdMZd4dDeddfd}dQdRZdudSdTZ	Ud~ddZd[Zdd\d]Zdd`daZdbdDeedDdDddcddhdiZdbdDeedDdDddcddjdkZ  Z S )
Dispatcherz
    Root router
    NF)storagefsm_strategyevents_isolationdisable_fsmnamer0   Optional[BaseStorage]r1   r   r2   Optional[BaseEventIsolation]r3   boolr4   Optional[str]kwargsr   returnNonec                  s   t t| j|d |rt|tstdt|j t| dd | _	| j
d< | j	| j | j	t|  | j	t  t|pAt ||pFt d| _|sS| j	| j | j| jj || _t | _d| _d| _t | _dS )a  
        Root router

        :param storage: Storage for FSM
        :param fsm_strategy: FSM strategy
        :param events_isolation: Events isolation
        :param disable_fsm: Disable FSM, note that if you disable FSM
            then you should not use storage and events isolation
        :param kwargs: Other arguments, will be passed as keyword arguments to handlers
        )r4   z4FSM storage should be instance of 'BaseStorage' not update)router
event_name)r0   strategyr2   N)superr/   __init__
isinstancer   	TypeErrortype__name__r'   r<   	observersregister_listen_updateouter_middlewarer(   r)   r   r   r   fsmshutdowncloseworkflow_datar   _running_lock_stop_signal_stopped_signalset_handle_update_tasks)selfr0   r1   r2   r3   r4   r9   	__class__ P/var/www/html/venv/lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.pyrA   &   s0   zDispatcher.__init__itemstrc                 C  s
   | j | S NrM   )rS   rX   rV   rV   rW   __getitem__d   s   
zDispatcher.__getitem__keyvaluec                 C  s   || j |< d S rZ   r[   )rS   r]   r^   rV   rV   rW   __setitem__g      zDispatcher.__setitem__c                 C  s   | j |= d S rZ   r[   )rS   r]   rV   rV   rW   __delitem__j   s   zDispatcher.__delitem__defaultOptional[Any]c                C  s   | j ||S rZ   )rM   get)rS   r]   rb   rV   rV   rW   rd   m   r`   zDispatcher.getr   c                 C  s   | j jS rZ   )rJ   r0   rS   rV   rV   rW   r0   p   s   zDispatcher.storageOptional[Router]c                 C  s   dS )z}
        Dispatcher has no parent router and can't be included to any other routers or dispatchers

        :return:
        NrV   re   rV   rV   rW   parent_routert   s   zDispatcher.parent_routerr*   c                 C  s   t d)z
        Dispatcher is root Router then configuring parent router is not allowed

        :param value:
        :return:
        z1Dispatcher can not be attached to another Router.)RuntimeError)rS   r^   rV   rV   rW   rg   }   s   botr   r<   r   c           
        s   t  }d}| }|j|krtj| d|id}z7| j| jj	|i | j
|d|iI dH }|tu}|W | }|| d }	tjd|j|rLdnd|	|j S | }|| d }	tjd|j|rgdnd|	|j w )	z
        Main entry point for incoming updates
        Response of this method can be used as Webhook response

        :param bot:
        :param update:
        Fri   contextNi  z/Update id=%s is %s. Duration %d ms by bot id=%dhandledznot handled)asyncioget_running_looptimeri   r   model_validate
model_dumpr<   wrap_outer_middlewaretriggerrM   r%   r   eventinfo	update_idid)
rS   ri   r<   r9   looprl   
start_timeresponsefinish_timedurationrV   rV   rW   feed_update   sL   

	

zDispatcher.feed_updateDict[str, Any]c                   s0   t j|d|id}| jd||d|I dH S )z
        Main entry point for incoming updates with automatic Dict->Update serializer

        :param bot:
        :param update:
        :param kwargs:
        ri   rj   ri   r<   NrV   )r   rp   _feed_webhook_update)rS   ri   r<   r9   parsed_updaterV   rV   rW   feed_raw_update   s   zDispatcher.feed_raw_update   polling_timeoutintbackoff_configr#   allowed_updatesOptional[List[str]]AsyncGenerator[Update, None]c              
   C s   t |d}t||d}i }|jjrt|jj| |d< d}	 z||fi |I dH }	W n2 ty^ }
 z&d}tjdt	|
j
|
 tjd|j|j|j | I dH  W Y d}
~
qd}
~
ww |rqtjd	|j|j |  d}|	D ]}|V  |jd
 |_qsq)z
        Endless updates reader with correctly handling any server-side or connection errors.

        So you may not worry that the polling will stop working.
        )config)timeoutr   request_timeoutFTNz Failed to fetch updates - %s: %szASleep for %f seconds and try again... (tryings = %d, bot id = %d)z2Connection established (tryings = %d, bot id = %d)r$   )r"   r   sessionr   r   	Exceptionr   
dispatchererrorrD   rE   warning
next_delaycounterrw   asleepru   resetrv   offset)clsri   r   r   r   backoffget_updatesr9   failedupdateser<   rV   rV   rW   _listen_updates   sF   
zDispatcher._listen_updatesc              
     sv   z|j }|j}W n ty& } ztd|jdd t t |d}~ww |j|d | j	d||d|I dH S )a  
        Main updates listener

        Workflow:
        - Detect content type and propagate to observers in current router
        - If no one filter is pass - propagate update to child routers as Update

        :param update:
        :param kwargs:
        :return:
        zDetected unknown update type.
Seems like Telegram Bot API was updated and you have installed not latest version of aiogram framework
Update: T)exclude_unsetN)event_update)update_typert   rV   )

event_typert   r!   warningswarnmodel_dump_jsonRuntimeWarningr&   r<   propagate_event)rS   r<   r9   r   rt   r   rV   rV   rW   rH      s    


zDispatcher._listen_updateresultTelegramMethod[Any]c              
     sR   z
||I dH  W dS  t y( } ztjd|jj| W Y d}~dS d}~ww )zk
        Simulate answer into WebHook

        :param bot:
        :param result:
        :return:
        NzFailed to make answer: %s: %s)r   r   rt   r   rU   rE   )r   ri   r   r   rV   rV   rW   silent_call_request  s   	"zDispatcher.silent_call_requestTcall_answerc              
     s   z#| j ||fi |I dH }|r t|tr | j||dI dH  |tuW S  tyE } ztjd|j	|j
|jj| W Y d}~dS d}~ww )aL  
        Propagate update to event listeners

        :param bot: instance of Bot
        :param update: instance of Update
        :param call_answer: need to execute response as Telegram method (like answer into webhook)
        :param kwargs: contextual data for middlewares, filters and handlers
        :return: status
        Nri   r   >Cause exception while process update id=%d by bot id=%d
%s: %sT)r}   rB   r   r   r%   r   r   rt   	exceptionrv   rw   rU   rE   )rS   ri   r<   r   r9   rz   r   rV   rV   rW   _process_update(  s"   
zDispatcher._process_updatehandle_updateAwaitable[bool]	semaphoreasyncio.Semaphorec                   s"   z
|I dH W |   S |   w )a  
        Process update with semaphore to limit concurrent tasks

        :param handle_update: Coroutine that processes the update
        :param semaphore: Semaphore to limit concurrent tasks
        :return: bool indicating the result of the update processing
        N)release)rS   r   r   rV   rV   rW   _process_with_semaphoreD  s   

z"Dispatcher._process_with_semaphorehandle_as_taskstasks_concurrency_limitOptional[int]c                   s  |  I dH }tjd|j|j|j d}	|dur!|r!t|}	zX| j	||||d2 z>3 dH W }
| j
d||
d|}|rd|	rQ|	 I dH  t| ||	}nt|}| j| || jj q+|I dH  q+6 W tjd|j|j|j dS tjd|j|j|j w )a  
        Internal polling process

        :param bot:
        :param polling_timeout: Long-polling wait time
        :param handle_as_tasks: Run task for each event and no wait result
        :param backoff_config: backoff-retry config
        :param allowed_updates: List of the update types you want your bot to receive
        :param tasks_concurrency_limit: Maximum number of concurrent updates to process
            (None = no limit), used only if handle_as_tasks is True
        :param kwargs:
        :return:
        Nz"Run polling for bot @%s id=%d - %r)r   r   r   r   z&Polling stopped for bot @%s id=%d - %rrV   )mer   r   ru   usernamerw   	full_namerm   	Semaphorer   r   acquirecreate_taskr   rR   addadd_done_callbackdiscard)rS   ri   r   r   r   r   r   r9   userr   r<   r   handle_update_taskrV   rV   rW   _pollingS  s@   


zDispatcher._pollingc              
     sV   z| j ||fi |I dH W S  ty* } ztjd|j|j|jj|  d}~ww )zg
        The same with `Dispatcher.process_update()` but returns real response instead of bool
        Nr   )	r}   r   r   rt   r   rv   rw   rU   rE   )rS   ri   r<   r9   r   rV   rV   rW   r     s   zDispatcher._feed_webhook_update7   Union[Update, Dict[str, Any]]_timeoutfloat&Optional[TelegramMethod[TelegramType]]c                   s&  t |tstj|d id}t }t }| dfdd}|||}t	j
d |d	|}	|	j||d d fdd}
zHzI d H  W n ty^   |	| |	   w |	 rt|	 }t |trs|W |  S n|	| |	j|
|d W |  d S W |  d S |  w )Nri   rj   _r   r:   r;   c                    s      s d  d S d S rZ   )done
set_result)r   )waiterrV   rW   release_waiter  s   z6Dispatcher.feed_webhook_update.<locals>.release_waiterr   taskFuture[Any]c              
     s\   t dt z|  }W n ty } z|d }~ww t|tr,tj	 |d d S d S )NzDetected slow response into webhook.
Telegram is waiting for response only first 60 seconds and then re-send update.
For preventing this situation response into webhook returned immediately and handler is moved to background and still processing update.r   )
r   r   r   r   r   rB   r   rm   ensure_futurer   )r   r   r   )ri   rS   rV   rW   process_response  s   
z8Dispatcher.feed_webhook_update.<locals>.process_response)r   r   r:   r;   rV   )r   r   r:   r;   )rB   r   rp   contextvarscopy_contextrm   rn   create_future
call_laterr   r   r   r   remove_done_callbackcancelr   r   r   )rS   ri   r<   r   r9   ctxrx   r   timeout_handleprocess_updatesr   rz   rV   )ri   rS   r   rW   feed_webhook_update  sF   





zDispatcher.feed_webhook_updatec                   sB   | j  s
td| jr| jsdS | j  | j I dH  dS )zd
        Execute this method if you want to stop polling programmatically

        :return:
        zPolling is not startedN)rN   lockedrh   rO   rP   rQ   waitre   rV   rV   rW   stop_polling  s   

zDispatcher.stop_pollingsigsignal.Signalsc                 C  s6   | j  sd S tjd|j | jsd S | j  d S )NzReceived %s signal)rN   r   r   r   r   r4   rO   rQ   )rS   r   rV   rV   rW   _signal_stop_polling  s   
zDispatcher._signal_stop_polling
   r   r   r   r   handle_signalsclose_bot_sessionr   bots&Optional[Union[List[str], UNSET_TYPE]]r   r   c                  s  |st dd|	v rt dj4 I dH Y jdu r!t _jdu r*t _ tu r2  j  j  |rjt	 }
t
t |
tjjtj |
tjjtj W d   n1 sew   Y  |dj|	dv r}d jdd|d iI dH  tjd z fdd	|D }|tj  tj|tjd
I dH \}}|D ]}|  t
t |I dH  W d   n1 sw   Y  qtj| I dH  W tjd z!jdd|d iI dH  W |rtjdd |D  I dH  n|rtjdd |D  I dH  w w j  n@tjd z!jdd|d iI dH  W |rLtjdd |D  I dH  n|r^tjdd |D  I dH  w w j  w W d  I dH  dS 1 I dH sww   Y  dS )a  
        Polling runner

        :param bots: Bot instances (one or more)
        :param polling_timeout: Long-polling wait time
        :param handle_as_tasks: Run task for each event and no wait result
        :param backoff_config: backoff-retry config
        :param allowed_updates: List of the update types you want your bot to receive
               By default, all used update types are enabled (resolved from handlers)
        :param handle_signals: handle signals (SIGINT/SIGTERM)
        :param close_bot_session: close bot sessions on shutdown
        :param tasks_concurrency_limit: Maximum number of concurrent updates to process
            (None = no limit), used only if handle_as_tasks is True
        :param kwargs: contextual data
        :return:
        z6At least one bot instance is required to start pollingri   zbKeyword argument 'bot' is not acceptable, the bot instance should be passed as positional argumentN)r   r   zStart pollingc                   s0   g | ]}t jd| d qS ))ri   r   r   r   r   r   rV   )rm   r   r   .0ri   r   r   r   r   rS   r   rM   rV   rW   
<listcomp>8  s    z,Dispatcher.start_polling.<locals>.<listcomp>)return_whenzPolling stoppedc                 s  s    | ]}|j  V  qd S rZ   )r   rL   r   rV   rV   rW   	<genexpr>W  s    z+Dispatcher.start_polling.<locals>.<genexpr>rV   ) 
ValueErrorrN   rO   r   rP   r   resolve_used_update_typesclearrm   rn   r   NotImplementedErroradd_signal_handlersignalSIGTERMr   SIGINTrM   popemit_startupr   r   ru   appendr   r   FIRST_COMPLETEDr   r   gatheremit_shutdownrQ   )rS   r   r   r   r   r   r   r   r   r9   rx   tasksr   pendingr   rV   r   rW   start_polling  s   






  0zDispatcher.start_pollingc          
      O  sV   t t t| j|i |	|||||||dW  d   S 1 s$w   Y  dS )a  
        Run many bots with polling

        :param bots: Bot instances (one or more)
        :param polling_timeout: Long-polling wait time
        :param handle_as_tasks: Run task for each event and no wait result
        :param backoff_config: backoff-retry config
        :param allowed_updates: List of the update types you want your bot to receive
        :param handle_signals: handle signals (SIGINT/SIGTERM)
        :param close_bot_session: close bot sessions on shutdown
        :param tasks_concurrency_limit: Maximum number of concurrent updates to process
            (None = no limit), used only if handle_as_tasks is True
        :param kwargs: contextual data
        :return:
        r   N)r   KeyboardInterruptrm   runr   )
rS   r   r   r   r   r   r   r   r   r9   rV   rV   rW   run_pollingZ  s"   
$zDispatcher.run_polling)r0   r5   r1   r   r2   r6   r3   r7   r4   r8   r9   r   r:   r;   )rX   rY   r:   r   )r]   rY   r^   r   r:   r;   )r]   rY   r:   r;   rZ   )rb   rc   r]   rY   r:   rc   )r:   r   )r:   rf   )r^   r*   r:   r;   )ri   r   r<   r   r9   r   r:   r   )ri   r   r<   r~   r9   r   r:   r   )
ri   r   r   r   r   r#   r   r   r:   r   )r<   r   r9   r   r:   r   )ri   r   r   r   r:   r;   )T)
ri   r   r<   r   r   r7   r9   r   r:   r7   )r   r   r   r   r:   r7   )ri   r   r   r   r   r7   r   r#   r   r   r   r   r9   r   r:   r;   )r   )
ri   r   r<   r   r   r   r9   r   r:   r   )r:   r;   )r   r   r:   r;   )r   r   r   r   r   r7   r   r#   r   r   r   r7   r   r7   r   r   r9   r   r:   r;   )!rE   
__module____qualname____doc__r   USER_IN_CHATrA   r\   r_   ra   rd   propertyr0   rg   setterr}   r   classmethodDEFAULT_BACKOFF_CONFIGr   rH   r   r   r   r   r   r   r   r   r   r   r  __classcell__rV   rV   rT   rW   r/   !   st    
>


	
-
9

<
;
mr/   )B
__future__r   rm   r   r   r   r   r   r   r   
contextlibr   typingr   r	   r
   r   r   r   r   r    r   
client.botr   
exceptionsr   fsm.middlewarer   fsm.storage.baser   r   fsm.storage.memoryr   r   fsm.strategyr   methodsr   r   methods.baser   typesr   r   
types.baser   r    types.updater!   utils.backoffr"   r#   event.basesr%   r&   event.telegramr'   middlewares.errorr(   middlewares.user_contextr)   r=   r*   r
  r/   rV   rV   rV   rW   <module>   s8    (