a
    y{Jh3                     @  s  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	 d dl
mZmZmZ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mZmZmZmZmZmZm Z m!Z!m"Z"m#Z# ed	eeZ$ed
Z%G dd dee$ eZ&dddddZ'G dd de&e Z(G dd de&e Z)dS )    )annotations)ABC)deepcopy)chain)cycle)TYPE_CHECKINGAny	GeneratorGenericIterableListOptionalTypeTypeVarUnioncast)CallbackData)CallbackGameInlineKeyboardButtonInlineKeyboardMarkupKeyboardButtonKeyboardButtonPollTypeKeyboardButtonRequestChatKeyboardButtonRequestUsersLoginUrlReplyKeyboardMarkupSwitchInlineQueryChosenChat
WebAppInfo
ButtonTypeTc                   @  s*  e Zd ZU dZdZded< dZded< dZded< d>dd	d
dddZe	ddddZ
dddddZdddddZdddddZdddd d!Zd"dd#d$d%Zddd&d'Zdd(dd)d*Zdd+dd,d(d-d.d/Zd0d1ddd(d2d3d4Zd"d(d5d6d7Zd"d8d5d9d:Zd(d(d;d<d=ZdS )?KeyboardBuilderz
    Generic keyboard builder that helps to adjust your markup with defined shape of lines.

    Works both of InlineKeyboardMarkup and ReplyKeyboardMarkup.
    r   int	max_width	min_widthmax_buttonsNzType[ButtonType]z Optional[List[List[ButtonType]]]None)button_typemarkupreturnc                 C  sB   t |ttfstd| d|| _|r4| | ng }|| _d S )NzButton type z are not allowed here)
issubclassr   r   
ValueError_button_type_validate_markup_markup)selfr&   r'    r/   H/var/www/shaz/venv/lib/python3.9/site-packages/aiogram/utils/keyboard.py__init__3   s    zKeyboardBuilder.__init__z!Generator[ButtonType, None, None])r(   c                 c  s   t |  E dH  dS )zB
        Get flatten set of all buttons

        :return:
        N)r   from_iterableexportr.   r/   r/   r0   buttons?   s    zKeyboardBuilder.buttonsr   bool)buttonr(   c                 C  s4   | j }t||s0t|d|jdt|jdS )zb
        Check that button item has correct type

        :param button:
        :return:
        z should be type z not T)r+   
isinstancer*   __name__type)r.   r7   allowedr/   r/   r0   _validate_buttonH   s    
z KeyboardBuilder._validate_button)r5   r(   c                 G  s   t t| j|S )zi
        Check that all passed button has correct type

        :param buttons:
        :return:
        )allmapr<   )r.   r5   r/   r/   r0   _validate_buttonsV   s    z!KeyboardBuilder._validate_buttonszList[ButtonType])rowr(   c                 C  sb   t |ts.td|d| jj dt|j t|| jkrTtd|d| j d| j|  dS )z
        Check that row of buttons are correct
        Row can be only list of allowed button types and has length 0 <= n <= 8

        :param row:
        :return:
        zRow z should be type 'List[z]' not type z is too long (max width: )T)	r8   listr*   r+   r9   r:   lenr"   r?   )r.   r@   r/   r/   r0   _validate_row_   s    

zKeyboardBuilder._validate_rowzList[List[ButtonType]]r'   r(   c                 C  sj   d}t |ts,td| jj dt|j|D ]}| | |t|7 }q0|| jkrftd| j dS )z
        Check that passed markup has correct data structure
        Markup is list of lists of buttons

        :param markup:
        :return:
        r   z!Markup should be type 'List[List[z]]' not type z.Too much buttons detected Max allowed count - T)	r8   rB   r*   r+   r9   r:   rD   rC   r$   )r.   r'   countr@   r/   r/   r0   r,   q   s    


z KeyboardBuilder._validate_markupr   )sizer(   c                 C  sL   t |tstd|t| j| jd vrHtd| d| j d| j d|S )z[
        Validate that passed size is legit

        :param size:
        :return:
        zOnly int sizes are allowed   z	Row size z is not allowed, range: [z, ])r8   r!   r*   ranger#   r"   )r.   rG   r/   r/   r0   _validate_size   s    
zKeyboardBuilder._validate_sizec                 C  s
   t | jS )aB  
        Export configured markup as list of lists of buttons

        .. code-block:: python

            >>> builder = KeyboardBuilder(button_type=InlineKeyboardButton)
            >>> ... # Add buttons to builder
            >>> markup = InlineKeyboardMarkup(inline_keyboard=builder.export())

        :return:
        )r   r-   r4   r/   r/   r0   r3      s    zKeyboardBuilder.exportz'KeyboardBuilder[ButtonType]'c                 G  s   | j |  |  }|rbt|d | jk rb|d }| jt| }|d| ||d  }}|| |r|d| j || jd  }}|t| qb|| _| S )z^
        Add one or many buttons to markup.

        :param buttons:
        :return:
        N)r?   r3   rC   r"   extendappendrB   r-   )r.   r5   r'   last_rowposheadr@   r/   r/   r0   add   s    

zKeyboardBuilder.add)widthzOptional[int])r5   rS   r(   c                  sN   du r| j |  | j   | j fddtdt D  | S )z
        Add row to markup

        When too much buttons is passed it will be separated to many rows

        :param buttons:
        :param width:
        :return:
        Nc                 3  s"   | ]}t  ||  V  qd S N)rB   ).0rP   r5   rS   r/   r0   	<genexpr>   s   z&KeyboardBuilder.row.<locals>.<genexpr>r   )r"   rK   r?   r-   rM   rJ   rC   )r.   rS   r5   r/   rV   r0   r@      s    

zKeyboardBuilder.rowF)repeat)sizesrX   r(   c          	      G  s   |s| j f}t| j|}|r$t|nt|}t|}g }g }| jD ]0}t||krh|| t|}g }|| qB|r|| || _	| S )a  
        Adjust previously added buttons to specific row sizes.

        By default, when the sum of passed sizes is lower than buttons count the last
        one size will be used for tail of the markup.
        If repeat=True is passed - all sizes will be cycled when available more buttons
        count than all sizes

        :param sizes:
        :param repeat:
        :return:
        )
r"   r>   rK   
repeat_allrepeat_lastnextr5   rC   rN   r-   )	r.   rX   rY   Zvalidated_sizesZ
sizes_iterrG   r'   r@   r7   r/   r/   r0   adjust   s"    


zKeyboardBuilder.adjustkwargsr(   c                 K  s<   t |dd }tr"| |d< | jf i |}| |S )zO
        Add button to markup

        :param kwargs:
        :return:
        callback_dataN)r8   getr   packr+   rR   )r.   r_   r`   r7   r/   r/   r0   _button   s    zKeyboardBuilder._buttonz0Union[InlineKeyboardMarkup, ReplyKeyboardMarkup]c                 K  sR   | j tu r2tttt  |  }tf d|i|S tttt  |  }t|dS )Nkeyboardinline_keyboard)r+   r   r   r   r3   r   r   r   )r.   r_   rd   rf   r/   r/   r0   	as_markup   s
    
zKeyboardBuilder.as_markup)builderr(   c                 C  sZ   t |tstdt|j |j| jurFtd| jj d|jj | j|  | S )Nz*Only KeyboardBuilder can be attached, not z9Only builders with same button type can be attached, not z and )	r8   r    r*   r:   r9   r+   r-   rM   r3   )r.   rh   r/   r/   r0   attach  s    
zKeyboardBuilder.attach)N)r9   
__module____qualname____doc__r"   __annotations__r#   r$   r1   propertyr5   r<   r?   rD   r,   rK   r3   rR   r@   r]   rc   rg   ri   r/   r/   r/   r0   r    (   s*   
 	!r    zIterable[T]zGenerator[T, None, None])itemsr(   c                 c  sh   t | }zt|}W n ty(   Y d S 0 |V  d}|s\zt|}W n tyZ   d}Y n0 |V  q4d S )NFT)iterr\   StopIteration)ro   Z
items_itervaluefinishedr/   r/   r0   r[     s    
r[   c                      s   e Zd ZU dZdZded< dZded< dZde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Ze	rdddddZ
d(ddd fdd Zddd!d"d#Zed$ddd%d&d'Z  ZS ))InlineKeyboardBuilderzK
    Inline keyboard builder inherits all methods from generic builder
       r!   r"   rH   r#   d   r$   N)	urlr`   web_app	login_urlswitch_inline_query switch_inline_query_current_chatswitch_inline_query_chosen_chatcallback_gamepaystrzOptional[str]z"Optional[Union[str, CallbackData]]Optional[WebAppInfo]zOptional[LoginUrl]z%Optional[SwitchInlineQueryChosenChat]zOptional[CallbackGame]Optional[bool]r   z'InlineKeyboardBuilder')textrw   r`   rx   ry   rz   r{   r|   r}   r~   r_   r(   c       
         K  s,   t t| jf |||||||||	|
d
|S )N)
r   rw   r`   rx   ry   rz   r{   r|   r}   r~   )r   rt   rc   )r.   r   rw   r`   rx   ry   rz   r{   r|   r}   r~   r_   r/   r/   r0   r7   -  s"    zInlineKeyboardBuilder.buttonr   r^   c                 K  s   dS )z!Construct an InlineKeyboardMarkupNr/   r.   r_   r/   r/   r0   rg   O  s    zInlineKeyboardBuilder.as_markupz*Optional[List[List[InlineKeyboardButton]]]r%   rE   c                   s   t  jt|d d S N)r&   r'   )superr1   r   r.   r'   	__class__r/   r0   r1   S  s    zInlineKeyboardBuilder.__init__r.   r(   c                 C  s   t |  dS zQ
        Make full copy of current builder with markup

        :return:
        r'   )rt   r3   r4   r/   r/   r0   copyV  s    zInlineKeyboardBuilder.copyzType['InlineKeyboardBuilder'])clsr'   r(   c                 C  s   | |j dS z^
        Create builder from existing markup

        :param markup:
        :return:
        r   re   r   r'   r/   r/   r0   from_markup^  s    
z!InlineKeyboardBuilder.from_markup)Nr9   rj   rk   rl   r"   rm   r#   r$   r7   r   rg   r1   r   classmethodr   __classcell__r/   r/   r   r0   rt   $  s(   
( rt   c                      s   e Zd ZU dZdZded< dZded< dZded< d	d	d	d	d	d	d
dddddddddd	ddZe	rtdddddZ
d$ddd fddZdddd d!Zedddd"d#Z  ZS )%ReplyKeyboardBuilderzJ
    Reply keyboard builder inherits all methods from generic builder
    
   r!   r"   rH   r#   i,  r$   N)request_usersrequest_chatrequest_contactrequest_locationrequest_pollrx   r   z$Optional[KeyboardButtonRequestUsers]z#Optional[KeyboardButtonRequestChat]r   z Optional[KeyboardButtonPollType]r   r   z'ReplyKeyboardBuilder')	r   r   r   r   r   r   rx   r_   r(   c          	      K  s&   t t| jf |||||||d|S )N)r   r   r   r   r   r   rx   )r   r   rc   )	r.   r   r   r   r   r   r   rx   r_   r/   r/   r0   r7   t  s    zReplyKeyboardBuilder.buttonr   r^   c                 K  s   d S rT   r/   r   r/   r/   r0   rg     s    zReplyKeyboardBuilder.as_markupz$Optional[List[List[KeyboardButton]]]r%   rE   c                   s   t  jt|d d S r   )r   r1   r   r   r   r/   r0   r1     s    zReplyKeyboardBuilder.__init__r   c                 C  s   t |  dS r   )r   r3   r4   r/   r/   r0   r     s    zReplyKeyboardBuilder.copyc                 C  s   | |j dS r   )rd   r   r/   r/   r0   r     s    z ReplyKeyboardBuilder.from_markup)Nr   r/   r/   r   r0   r   k  s"   
"r   N)*
__future__r   abcr   r   r   	itertoolsr   r   rZ   typingr   r   r	   r
   r   r   r   r   r   r   r   Zaiogram.filters.callback_datar   Zaiogram.typesr   r   r   r   r   r   r   r   r   r   r   r   r   r    r[   rt   r   r/   r/   r/   r0   <module>   s   44 kG