a
    9gZ                     @  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 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l/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> e3dddddZ?G dd  d e>Z@dS )!    )annotationsN)CancelledErrorEventFutureLock)suppress)AnyAsyncGenerator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?)Z	min_delayZ	max_delayZfactorjitterc                      s  e Zd ZdZdejddddddddd	d
dd fddZdd
dddZdd
ddddZdddddZ	d\ddddddZ
edddd Zed!dd"d#Zejd$dd%d&d#Zd'd(d
d
d)d*d+Zd'd,d
d
d)d-d.Zed/edfd'd0d1d2d3d4d5d6Zd(d
d
d7d8d9Zed'd:dd;d<d=Zd]d'd(dd
dd?d@dAZd/d>edfd'd0dd1d2d
ddBdCdDZd'd(d
d
d)dEdFZd^d'dHdId
dJdKdLdMZdddNdOZdPddQdRdSZdTd>eed>d>dUd'd0dd1dVddd
ddW	dXdYZdTd>eed>d>dUd'd0dd1dVddd
ddW	dZd[Z  ZS )_
Dispatcherz
    Root router
    NF)storagefsm_strategyevents_isolationdisable_fsmnamezOptional[BaseStorage]r   zOptional[BaseEventIsolation]boolzOptional[str]r   None)r,   r-   r.   r/   r0   kwargsreturnc                  s   t t| j|d |r4t|ts4tdt|j t| dd | _	| j
d< | j	| j | j	t|  | j	t  t|pt ||pt d| _|s| 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
        )r0   z4FSM storage should be instance of 'BaseStorage' not update)routerZ
event_name)r,   Zstrategyr.   N)superr+   __init__
isinstancer   	TypeErrortype__name__r&   r5   Z	observersregister_listen_updateZouter_middlewarer'   r(   r   r   r   fsmshutdowncloseworkflow_datar   _running_lock_stop_signal_stopped_signalset_handle_update_tasks)selfr,   r-   r.   r/   r0   r3   	__class__ z/var/www/vosh/data/www/fastworkle.ru/webshop-tgbot-v.1.0/venv/lib/python3.9/site-packages/aiogram/dispatcher/dispatcher.pyr8   &   s0    zDispatcher.__init__str)itemr4   c                 C  s
   | j | S NrB   )rH   rN   rK   rK   rL   __getitem__d   s    zDispatcher.__getitem__)keyvaluer4   c                 C  s   || j |< d S rO   rP   )rH   rR   rS   rK   rK   rL   __setitem__g   s    zDispatcher.__setitem__)rR   r4   c                 C  s   | j |= d S rO   rP   )rH   rR   rK   rK   rL   __delitem__j   s    zDispatcher.__delitem__zOptional[Any])defaultrR   r4   c                C  s   | j ||S rO   )rB   get)rH   rR   rV   rK   rK   rL   rW   m   s    zDispatcher.getr   )r4   c                 C  s   | j jS rO   )r?   r,   rH   rK   rK   rL   r,   p   s    zDispatcher.storagez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:
        NrK   rX   rK   rK   rL   parent_routert   s    zDispatcher.parent_routerr)   )rS   r4   c                 C  s   t ddS )z
        Dispatcher is root Router then configuring parent router is not allowed

        :param value:
        :return:
        z1Dispatcher can not be attached to another Router.N)RuntimeError)rH   rS   rK   rK   rL   rY   }   s    r   r   )botr5   r3   r4   c           
        s   t  }d}| }|j|kr4tj| d|id}z|| j| jj	|i | j
|d|iI dH }|tu}|W | }|| d }	tjd|j|rdnd|	|j S d|	|j n8| }|| d }	tjd|j| rdnd|	|j 0 dS )	z
        Main entry point for incoming updates
        Response of this method can be used as Webhook response

        :param bot:
        :param update:
        Fr[   contextNi  z/Update id=%s is %s. Duration %d ms by bot id=%dhandledznot handled)asyncioget_running_looptimer[   r   model_validateZ
model_dumpr5   Zwrap_outer_middlewaretriggerrB   r$   r   eventinfo	update_idid)
rH   r[   r5   r3   loopr^   
start_timeresponseZfinish_timedurationrK   rK   rL   feed_update   s^    

	
     zDispatcher.feed_updatezDict[str, Any]c                   s.   t j|d|id}| jf ||d|I dH S )z
        Main entry point for incoming updates with automatic Dict->Update serializer

        :param bot:
        :param update:
        :param kwargs:
        r[   r\   r[   r5   N)r   rb   _feed_webhook_update)rH   r[   r5   r3   Zparsed_updaterK   rK   rL   feed_raw_update   s    zDispatcher.feed_raw_update   intr"   zOptional[List[str]]zAsyncGenerator[Update, None])r[   polling_timeoutbackoff_configallowed_updatesr4   c              
   C s  t |d}t||d}i }|jjr6t|jj| |d< d}z||fi |I dH }	W np ty }
 zXd}tjdt	|
j
|
 tjd|j|j|j | I dH  W Y d}
~
q:W Y d}
~
n
d}
~
0 0 |rtjd	|j|j |  d}|	D ]}|V  |jd
 |_qq:dS )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)timeoutrt   request_timeoutFNTz 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   sessionrv   rq   	Exceptionr   
dispatchererrorr;   r<   warningZ
next_delaycounterrg   Zasleepre   resetrf   offset)clsr[   rr   rs   rt   backoffZget_updatesr3   failedZupdateser5   rK   rK   rL   _listen_updates   s<    
"zDispatcher._listen_updates)r5   r3   r4   c              
     s   z|j }|j}W nF tyV } z.td|jdd t t |W Y d}~n
d}~0 0 |j|d | j	f ||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)Zexclude_unsetN)Zevent_update)update_typerd   )
Z
event_typerd   r    warningswarnZmodel_dump_jsonRuntimeWarningr%   r5   Zpropagate_event)rH   r5   r3   r   rd   r   rK   rK   rL   r>      s    

zDispatcher._listen_updatezTelegramMethod[Any])r[   resultr4   c              
     sP   z||I dH  W n8 t yJ } z tjd|jj| W Y d}~n
d}~0 0 dS )zk
        Simulate answer into WebHook

        :param bot:
        :param result:
        :return:
        NzFailed to make answer: %s: %s)r   r   rd   r{   rJ   r<   )r   r[   r   r   rK   rK   rL   silent_call_request  s    	zDispatcher.silent_call_requestT)r[   r5   call_answerr3   r4   c              
     s   zF| j ||fi |I dH }|r>t|tr>| j||dI dH  |tuW S  ty } z*tjd|j	|j
|jj| W Y d}~dS d}~0 0 dS )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r[   r   >Cause exception while process update id=%d by bot id=%d
%s: %sT)rl   r9   r   r   r$   ry   r   rd   	exceptionrf   rg   rJ   r<   )rH   r[   r5   r   r3   rj   r   rK   rK   rL   _process_update(  s    
zDispatcher._process_update)r[   rr   handle_as_tasksrs   rt   r3   r4   c                   s   |  I dH }tjd|j|j|j z| j||||d2 zV3 dH W }| jf ||d|}	|rt	
|	}
| j|
 |
| jj q:|	I dH  q:6 W tjd|j|j|j ntjd|j|j|j 0 dS )zg
        Internal polling process

        :param bot:
        :param kwargs:
        :return:
        Nz"Run polling for bot @%s id=%d - %r)rr   rs   rt   rm   z&Polling stopped for bot @%s id=%d - %r)mer   rz   re   usernamerg   Z	full_namer   r   r_   create_taskrG   addadd_done_callbackdiscard)rH   r[   rr   r   rs   rt   r3   userr5   Zhandle_updateZhandle_update_taskrK   rK   rL   _pollingD  s,    
zDispatcher._pollingc              
     sd   z| j ||fi |I dH W S  ty^ } z*tjd|j|j|jj|  W Y d}~n
d}~0 0 dS )zg
        The same with `Dispatcher.process_update()` but returns real response instead of bool
        Nr   )	rl   ry   r   rd   r   rf   rg   rJ   r<   )rH   r[   r5   r3   r   rK   rK   rL   rn   k  s    zDispatcher._feed_webhook_update7   zUnion[Update, Dict[str, Any]]floatz&Optional[TelegramMethod[TelegramType]])r[   r5   _timeoutr3   r4   c                   s(  t |tstj|d id}t }t }| dddfdd}|||}t	j
f  |d|}	|	j||d d	dd
 fdd}
zzI d H  W n& ty   |	| |	   Y n0 |	 r|	 }t |tr|W |  S n|	| |	j|
|d W |  n
|  0 d S )Nr[   r\   r   r2   )_r4   c                    s      s d  d S rO   )doneZ
set_result)r   )waiterrK   rL   release_waiter  s    z6Dispatcher.feed_webhook_update.<locals>.release_waiterrm   zFuture[Any])taskr4   c              
     sd   t dt z|  }W n( ty@ } z|W Y d }~n
d }~0 0 t|tr`tj	 |d 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   ry   r9   r   r_   ensure_futurer   )r   r   r   )r[   rH   rK   rL   process_response  s    
z8Dispatcher.feed_webhook_update.<locals>.process_response)r9   r   rb   contextvarsZcopy_contextr_   r`   Zcreate_futureZ
call_laterr   rn   r   r   Zremove_done_callbackcancelr   r   r   )rH   r[   r5   r   r3   ctxrh   r   Ztimeout_handleZprocess_updatesr   rj   rK   )r[   rH   r   rL   feed_webhook_update{  s:    



zDispatcher.feed_webhook_updatec                   s@   | 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)rC   lockedrZ   rD   rE   rF   waitrX   rK   rK   rL   stop_polling  s    

zDispatcher.stop_pollingzsignal.Signals)sigr4   c                 C  s6   | j  sd S tjd|j | js(d S | j  d S )NzReceived %s signal)rC   r   r   rz   r|   r0   rD   rF   )rH   r   rK   rK   rL   _signal_stop_polling  s    
zDispatcher._signal_stop_polling
   rr   r   rs   rt   handle_signalsclose_bot_sessionz&Optional[Union[List[str], UNSET_TYPE]])	botsrr   r   rs   rt   r   r   r3   r4   c                  s  |st dd|v rt dj4 I dH  jdu r@t _jdu rRt _ tu rb  j  j  |rt	 }	t
t8 |	tjjtj |	tjjtj W d   n1 s0    Y  |dj|dv rd jf 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 ]B}|  t
t |I dH  W d   n1 s0    Y  qvtj| I dH  W tjd zBjf 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  0 j  n~tjd zBjf d|d iI dH  W |rtjdd |D  I dH  n"|rtjdd |D  I dH  0 j  0 W d  I dH  q1 I dH s0    Y  dS )al  
        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 kwargs: contextual data
        :return:
        z6At least one bot instance is required to start pollingr[   zbKeyword argument 'bot' is not acceptable, the bot instance should be passed as positional argumentN)rz   r   zStart pollingc                   s.   g | ]&}t jf | d qS ))r[   r   rr   rs   rt   )r_   r   r   .0r[   rt   rs   r   rr   rH   rB   rK   rL   
<listcomp>  s   z,Dispatcher.start_polling.<locals>.<listcomp>)Zreturn_whenzPolling stoppedc                 s  s   | ]}|j  V  qd S rO   )rx   rA   r   rK   rK   rL   	<genexpr>/      z+Dispatcher.start_polling.<locals>.<genexpr>) 
ValueErrorrC   rD   r   rE   r   Zresolve_used_update_typesclearr_   r`   r   NotImplementedErrorZadd_signal_handlersignalSIGTERMr   SIGINTrB   popZemit_startupr   rz   re   appendr   r   ZFIRST_COMPLETEDr   r   ZgatherZemit_shutdownrF   )rH   rr   r   rs   rt   r   r   r   r3   rh   Ztasksr   pendingr   rK   r   rL   start_polling  s|    




"

.  zDispatcher.start_pollingc          	      O  sT   t t8 t| j|i |||||||dW  d   S 1 sF0    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 kwargs: contextual data
        :return:
        r   N)r   KeyboardInterruptr_   runr   )	rH   rr   r   rs   rt   r   r   r   r3   rK   rK   rL   run_polling2  s    
zDispatcher.run_polling)N)T)r   ) r<   
__module____qualname____doc__r   ZUSER_IN_CHATr8   rQ   rT   rU   rW   propertyr,   rY   setterrl   ro   classmethodDEFAULT_BACKOFF_CONFIGr   r>   r   r   r   rn   r   r   r   r   r   r   __classcell__rK   rK   rI   rL   r+   !   sj   ">	-9 ' ;"ir+   )A
__future__r   r_   r   r   r   r   r   r   r   
contextlibr   typingr   r	   r
   r   r   r   r    r   Z
client.botr   
exceptionsr   Zfsm.middlewarer   Zfsm.storage.baser   r   Zfsm.storage.memoryr   r   Zfsm.strategyr   methodsr   r   Zmethods.baser   typesr   r   Z
types.baser   r   Ztypes.updater    Zutils.backoffr!   r"   Zevent.basesr$   r%   Zevent.telegramr&   Zmiddlewares.errorr'   Zmiddlewares.user_contextr(   r6   r)   r   r+   rK   rK   rK   rL   <module>   s6   $