o
    HEDiI;                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ej
r'ddlZdZdZd	ZG d
d deZG dd deZdedefddZdS )zt
This module has redis storage for finite-state machine based on `redis <https://pypi.org/project/redis/>`_ driver.
    N   )BaseStorage)json)
deprecatedstatedatabucketc                
   @   s  e Zd ZdZedddd9dd	Zd
d Zdd Zd:ddZdddde	j
eedf de	j
eedf de	jfddZddddddde	j
eedf de	j
eedf fddZddddde	j
eedf de	j
eedf de	je de	je fddZddddde	j
eedf de	j
eedf de	je de	jfddZdddd de	j
eedf de	j
eedf d!e	je	j fd"d#Zdddd$de	j
eedf de	j
eedf d%e	jfd&d'Zdddd$de	j
eedf de	j
eedf d%e	jfd(d)Zde	je	jeef  fd*d+Zd;d-d.Zd/d0 Zddddde	j
eedf de	j
eedf de	je de	jfd1d2Zdddd3de	j
eedf de	j
eedf d4e	jfd5d6Zdddd3de	j
eedf de	j
eedf d4e	jfd7d8ZdS )<RedisStorageaY  
    Simple Redis-base storage for FSM.

    Usage:

    .. code-block:: python3

        storage = RedisStorage('localhost', 6379, db=5)
        dp = Dispatcher(bot, storage=storage)

    And need to close Redis connection when shutdown

    .. code-block:: python3

        await dp.storage.close()
        await dp.storage.wait_closed()

    zL`RedisStorage` will be removed in aiogram v3.0. Use `RedisStorage2` instead.r   
stacklevel	localhost  Nc                 K   s8   || _ || _|| _|| _|| _|| _d | _t | _	d S N)
_host_port_db	_password_ssl_kwargs_redisasyncioLock_connection_lock)selfhostportdbpasswordsslloopkwargs r!   p/var/www/www-root/data/www/ovozai.pdev.uz/venv/lib/python3.10/site-packages/aiogram/contrib/fsm_storage/redis.py__init__)   s   zRedisStorage.__init__c              	      s   | j 4 I d H . | jr | jjs+| j  W d   I d H  d S W d   I d H  d S W d   I d H  d S 1 I d H s<w   Y  d S r   )r   r   closedcloser   r!   r!   r"   r%   6   s   .zRedisStorage.closec              	      sn   | j 4 I d H " | jr| j I d H W  d   I d H  S 	 W d   I d H  dS 1 I d H s0w   Y  d S NT)r   r   wait_closedr&   r!   r!   r"   r(   ;   s   0zRedisStorage.wait_closedreturnaioredis.RedisConnectionc              	      s   ddl }| j4 I dH / | jdu s| jjr/|j| j| jff| j| j| j	d| j
I dH | _W d  I dH  | jS 1 I dH sAw   Y  | jS )z&
        Get Redis connection
        r   N)r   r   r   )aioredisr   r   r$   create_connectionr   r   r   r   r   r   )r   r+   r!   r!   r"   redisA   s   zRedisStorage.redischatuserr/   r0   c                   s`   | j ||d\}}d| d| }|  I dH }|d|I dH }|du r+di dS t|S )ze
        Get record from storage

        :param chat:
        :param user:
        :return:
        r.   fsm::NGET)r   r   )check_addressr-   executer   loads)r   r/   r0   addrconnr   r!   r!   r"   
get_recordO   s   


zRedisStorage.get_recordr/   r0   r   r   r   c          	         s   |du ri }|du ri }| j ||d\}}d| d| }|  I dH }|du r@||  kr3i kr@n n|d|I dH  dS |||d}|d|t|I dH  dS )z
        Write record to storage

        :param bucket:
        :param chat:
        :param user:
        :param state:
        :param data:
        :return:
        Nr.   r1   r2   DEL)r   r   r   SET)r4   r-   r5   r   dumps)	r   r/   r0   r   r   r   r7   r8   recordr!   r!   r"   
set_recordb   s    zRedisStorage.set_recordr/   r0   defaultrA   c                   s(   | j ||dI d H }|d| |S )Nr.   r   )r9   getresolve_stater   r/   r0   rA   r>   r!   r!   r"   	get_state}   s   zRedisStorage.get_statec                   s   | j ||dI d H }|d S )Nr.   r   )r9   rD   r!   r!   r"   get_data   s   zRedisStorage.get_datar/   r0   r   r   c                   s@   | j ||dI d H }| |}| j||||d dI d H  d S )Nr.   r   r/   r0   r   r   )r9   rC   r?   )r   r/   r0   r   r>   r!   r!   r"   	set_state   s   
 zRedisStorage.set_stater/   r0   r   r   c                   s6   | j ||dI d H }| j|||d |dI d H  d S )Nr.   r   rH   r9   r?   )r   r/   r0   r   r>   r!   r!   r"   set_data   s    zRedisStorage.set_datac                   s`   |d u ri }| j ||dI d H }|di }|j|fi | | j|||d |dI d H  d S )Nr.   r   r   rH   r9   rB   updater?   )r   r/   r0   r   r    r>   record_datar!   r!   r"   update_data   s    zRedisStorage.update_datac                    sZ   |   I dH }g }|ddI dH }|D ]}|dd^ }}}|||f q|S )
        Get list of all stored chat's and user's

        :return: list of tuples where first element is chat id and second is user id
        NKEYSfsm:*zutf-8r2   )r-   r5   decodesplitappend)r   r8   resultkeysitem_r/   r0   r!   r!   r"   get_states_list   s   zRedisStorage.get_states_listTc                    sV   |   I dH }|r|dI dH  dS |ddI dH }|jdg|R  I dH  dS )i
        Reset states in DB

        :param full: clean DB or clean only states
        :return:
        NFLUSHDBrR   rS   r;   )r-   r5   )r   fullr8   rX   r!   r!   r"   	reset_all   s   zRedisStorage.reset_allc                 C      dS r'   r!   r&   r!   r!   r"   
has_bucket      zRedisStorage.has_bucketc                   s"   | j ||dI d H }|di S )Nr.   r   )r9   rB   rD   r!   r!   r"   
get_bucket   s   zRedisStorage.get_bucketr/   r0   r   r   c                   s<   | j ||dI d H }| j|||d |d |dI d H  d S )Nr.   r   r   r:   rK   )r   r/   r0   r   r>   r!   r!   r"   
set_bucket   s   &zRedisStorage.set_bucketc                   sb   | j ||dI d H }|di }|d u ri }|j|fi | | j|||d ||dI d H  d S )Nr.   r   r   r:   rM   )r   r/   r0   r   r    r>   record_bucketr!   r!   r"   update_bucket   s   "zRedisStorage.update_bucket)r   r   NNNN)r)   r*   T)__name__
__module____qualname____doc__r   r#   r%   r(   r-   typingUnionstrintDictr9   r?   OptionalrE   rF   AnyStrrI   rL   rP   ListTupler[   r_   ra   rc   re   rg   r!   r!   r!   r"   r	      s    

.&
&


&
&
	
&
&
r	   c                   @   s  e Zd ZdZ											dDdeded	eje d
eje deje dedeje	j
 dedeje deje deje fddZeddddEddZdd Zdd Zdd  Zdddd!d"ejeedf d#ejeedf d$eje deje fd%d&Zdddd!d"ejeedf d#ejeedf d$eje dejfd'd(Zdddd)d"ejeedf d#ejeedf d*ejej fd+d,Zdddd-d"ejeedf d#ejeedf d.ejfd/d0Zdddd-d"ejeedf d#ejeedf d.ejfd1d2Zd3d4 Zdddd!d"ejeedf d#ejeedf d$eje dejfd5d6Zdddd7d"ejeedf d#ejeedf d8ejfd9d:Zdddd7d"ejeedf d#ejeedf d8ejfd;d<ZdFd>d?Zdejej eef  fd@dAZ!dBdC Z"dS )GRedisStorage2a  
    Busted Redis-base storage for FSM.
    Works with Redis connection pool and customizable keys prefix.

    Usage:

    .. code-block:: python3

        storage = RedisStorage2('localhost', 6379, db=5, pool_size=10, prefix='my_fsm_key')
        dp = Dispatcher(bot, storage=storage)

    And need to close Redis connection when shutdown

    .. code-block:: python3

        await dp.storage.close()

    r   r   N
   fsmr   r   r   r   r   	pool_sizer   prefix	state_ttldata_ttl
bucket_ttlc              
   K   sJ   ddl m} |d||||||dd|| _|f| _|	| _|
| _|| _d S )Nr   )RedisT)r   r   r   r   r   max_connectionsdecode_responsesr!   )redis.asyncior~   r   _prefix
_state_ttl	_data_ttl_bucket_ttl)r   r   r   r   r   r   ry   r   rz   r{   r|   r}   r    r~   r!   r!   r"   r#      s    
zRedisStorage2.__init__zWThis method will be removed in aiogram v3.0. You should use your own instance of Redis.r   r
   r)   aioredis.Redisc                    s   | j S r   )r   r&   r!   r!   r"   r-   	  s   zRedisStorage2.redisc                 G   s   d | jttt| S )Nr2   )joinr   tuplemapro   )r   partsr!   r!   r"   generate_key  s   zRedisStorage2.generate_keyc                    s   | j  I d H  d S r   )r   r%   r&   r!   r!   r"   r%        zRedisStorage2.closec                    s   d S r   r!   r&   r!   r!   r"   r(     s   zRedisStorage2.wait_closedr@   r/   r0   rA   c                   s>   | j ||d\}}| ||t}| j|I d H p| |S Nr.   )r4   r   	STATE_KEYr   rB   rC   )r   r/   r0   rA   keyr!   r!   r"   rE     s   zRedisStorage2.get_statec                   J   | j ||d\}}| ||t}| j|I d H }|r!t|S |p$i S r   )r4   r   STATE_DATA_KEYr   rB   r   r6   r   r/   r0   rA   r   
raw_resultr!   r!   r"   rF        
zRedisStorage2.get_datarG   r   c                   sd   | j ||d\}}| ||t}|d u r | j|I d H  d S | jj|| || jdI d H  d S Nr.   )ex)r4   r   r   r   deletesetrC   r   )r   r/   r0   r   r   r!   r!   r"   rI   &  s   $zRedisStorage2.set_staterJ   r   c                   `   | j ||d\}}| ||t}|r%| jj|t|| jdI d H  d S | j|I d H  d S r   )	r4   r   r   r   r   r   r=   r   r   )r   r/   r0   r   r   r!   r!   r"   rL   /     $zRedisStorage2.set_datac                   sP   |d u ri }| j ||i dI d H }|j|fi | | j|||dI d H  d S )Nr@   rJ   )rF   rN   rL   )r   r/   r0   r   r    	temp_datar!   r!   r"   rP   8  s   zRedisStorage2.update_datac                 C   r`   r'   r!   r&   r!   r!   r"   ra   @  rb   zRedisStorage2.has_bucketc                   r   r   )r4   r   STATE_BUCKET_KEYr   rB   r   r6   r   r!   r!   r"   rc   C  r   zRedisStorage2.get_bucketrd   r   c                   r   r   )	r4   r   r   r   r   r   r=   r   r   )r   r/   r0   r   r   r!   r!   r"   re   L  r   zRedisStorage2.set_bucketc                   sN   |d u ri }| j ||dI d H }|j|fi | | j|||dI d H  d S )Nr.   rd   )rc   rN   re   )r   r/   r0   r   r    temp_bucketr!   r!   r"   rg   U  s   zRedisStorage2.update_bucketTc                    sH   |r| j  I dH  dS | j | dI dH }| j j| I dH  dS )r\   N*)r   flushdbrX   r   r   )r   r^   rX   r!   r!   r"   r_   ^  s
   zRedisStorage2.reset_allc                    sR   g }| j | ddtI dH }|D ]}|d^ }}}}|||f q|S )rQ   r   Nr2   )r   rX   r   r   rU   rV   )r   rW   rX   rY   rZ   r/   r0   r!   r!   r"   r[   k  s   zRedisStorage2.get_states_listc                    s   t || I d H  d S r   )migrate_redis1_to_redis2)r   redis1r!   r!   r"   import_redis1z  r   zRedisStorage2.import_redis1)r   r   NNNrw   Nrx   NNN)r)   r   rh   )#ri   rj   rk   rl   ro   rp   rm   rr   boolr   AbstractEventLoopr#   r   r-   r   r%   r(   rn   rE   dictrq   rF   rs   rI   rL   rP   ra   rc   re   rg   r_   rt   ru   r[   r   r!   r!   r!   r"   rv      s    
	

!&
&
	&

	&
	&
&
	&
	

	rv   storage1storage2c                    s   t | tstt|  dt |tstt| dtd}|  I dH D ]N\}}| j||dI dH }|j|||dI dH  | j	||dI dH }|j
|||dI dH  | j||dI dH }|j|||dI dH  |d| d	|  q)dS )
z
    Helper for migrating from RedisStorage to RedisStorage2

    :param storage1: instance of RedisStorage
    :param storage2: instance of RedisStorage2
    :return:
    z is not RedisStorage instance.zaiogram.RedisStorageNr.   rG   rJ   rd   zMigrated user z	 in chat )
isinstancer	   	TypeErrortypelogging	getLoggerr[   rE   rI   rF   rL   rc   re   info)r   r   logr/   r0   r   r   r   r!   r!   r"   r   ~  s   


r   )rl   r   r   rm   dispatcher.storager   utilsr   utils.deprecatedr   TYPE_CHECKINGr+   r   r   r   r	   rv   r   r!   r!   r!   r"   <module>   s"     @ +