U
    h                     @   s   d dl 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 ejrrddlmZ dZd	Zd	ZG d
d dZG dd deZG dd deZG dd deZG dd dZdS )    N   )helpersutilshintserrors)RequestIter)types	functionscustom   )TelegramClient   d   c                   @   s   e Zd Ze e e e e e	 e	 e
 e edededededededede dZdd Zdd Zdd ZejZejZd	d
 Zdd ZdS )_ChatActionr   )typingcontactZgamelocationZstickerzrecord-audiozrecord-voicezrecord-roundzrecord-videoaudioZvoiceZsongroundvideophotodocumentfilecancelc                C   s4   || _ || _|| _|| _|| _d | _d | _d| _d S NF)_client_chat_action_delay_auto_cancel_request_task_running)selfclientchatactiondelayauto_cancel r)   9/tmp/pip-unpacked-wheel-c81u5j2r/telethon/client/chats.py__init__-   s    z_ChatAction.__init__c                    sH   | j | jI d H | _tj| j| j| _d| _| j j	
|  | _| S NT)r   get_input_entityr   r	   messagesSetTypingRequestr   r    r"   ZloopZcreate_task_updater!   r#   r)   r)   r*   
__aenter__7   s     z_ChatAction.__aenter__c                    sH   d| _ | jrD| j  z| jI d H  W n tjk
r<   Y nX d | _d S r   )r"   r!   r   asyncioCancelledError)r#   argsr)   r)   r*   	__aexit__D   s    
z_ChatAction.__aexit__c              
      s   z0| j r.| | jI d H  t| jI d H  qW nN tk
rD   Y n< tjk
r~   | jrz| t	j
| jt I d H  Y nX d S N)r"   r   r    r3   sleepr   ConnectionErrorr4   r   r	   r.   r/   r   r   SendMessageCancelActionr1   r)   r)   r*   r0   R   s    
 z_ChatAction._updatec                 C   s$   t | jdr dt||  | j_d S )Nprogressr   )hasattrr   r   r;   )r#   currenttotalr)   r)   r*   r;   ^   s    z_ChatAction.progressN)__name__
__module____qualname__r   ZSendMessageTypingActionZSendMessageChooseContactActionZSendMessageGamePlayActionZSendMessageGeoLocationActionZSendMessageChooseStickerActionZSendMessageRecordAudioActionZSendMessageRecordRoundActionZSendMessageRecordVideoActionZSendMessageUploadAudioActionZSendMessageUploadRoundActionZSendMessageUploadVideoActionZSendMessageUploadPhotoActionZSendMessageUploadDocumentActionr:   _str_mappingr+   r2   r6   r   Z_sync_enter	__enter__Z
_sync_exit__exit__r0   r;   r)   r)   r)   r*   r      s4   
r   c                   @   s   e Zd Zdd Zdd ZdS )_ParticipantsIterc           
         s  t |tr2|tjtjtjtjfkr,|d}n| }| j|I d H }t	
|} rz|sb|t	jjkrz    fdd| _n
dd | _d | _|t	jjkr| jdkr| tj|I d H jj| _tt | _tjj||pt dtdd| _n$|t	jjkr| tj|jI d H }t |jj tj!s4d| _tt"|jj j | _dd |j#D }|jj j D ]j}t |tj$rvq^nt |tj%r|j&j'}n|j'}|| }	| |	sq^|| }	||	_(| j)*|	 q^d	S d
| _| jdkr| j+|I d H }	| |	rd |	_(| j)*|	 d	S d S )N c                    s*    t |  kp( t| dd p"d kS )NusernamerF   )r   Zget_display_namecasefoldgetattrentsearchr)   r*   <lambda>u   s    z)_ParticipantsIter._init.<locals>.<lambda>c                 S   s   dS r,   r)   rJ   r)   r)   r*   rN   z       r   channelfilteroffsetlimithashc                 S   s   i | ]}|j |qS r)   id.0userr)   r)   r*   
<dictcomp>   s      z+_ParticipantsIter._init.<locals>.<dictcomp>Tr   ),
isinstancetyper   ZChannelParticipantsBannedZChannelParticipantsKickedChannelParticipantsSearchZChannelParticipantsContactsr$   r-   r   _entity_type_EntityTypeCHANNELrH   filter_entityrequestsrT   r	   channelsGetFullChannelRequest	full_chatZparticipants_countr>   StopAsyncIterationsetseenGetParticipantsRequest_MAX_PARTICIPANTS_CHUNK_SIZECHATr.   GetFullChatRequestchat_idparticipantsZChatParticipantslenusersChannelParticipantLeftChannelParticipantBannedpeeruser_idparticipantbufferappend
get_entity)
r#   entityrR   rM   tyfullrq   rv   ru   rZ   r)   rL   r*   _initd   sz    






 
z_ParticipantsIter._initc              	      s  | j s
dS t| j| j j t| j _| j j| jkr4dS | jd kr| j j}t|tj	st|tj
rd|jr| tjj| j jt	 ddddI d H j| _| | j I d H }| jd kr|j| _|jsd | _ d S | j  jt|j7  _dd |jD }|jD ]}t|tjrqn0t|tjr2t|jtjs(q|jj}n|j}|| }| |r|j| jkrZq| j| || }||_| j | qd S )NTr   r   rP   c                 S   s   i | ]}|j |qS r)   rV   rX   r)   r)   r*   r[      s      z6_ParticipantsIter._load_next_chunk.<locals>.<dictcomp>)!rc   minrT   rS   rk   r>   rR   r\   r   ZChannelParticipantsRecentr^   qr$   r	   rd   rj   rQ   countrq   rp   ro   rr   rs   rt   ZPeerUserru   rb   rW   ri   addrv   rw   rx   )r#   fro   rq   rv   ru   rZ   r)   r)   r*   _load_next_chunk   sV    






z"_ParticipantsIter._load_next_chunkNr?   r@   rA   r}   r   r)   r)   r)   r*   rE   c   s   TrE   c                   @   s   e Zd Zdd Zdd ZdS )_AdminLogIterc                    s   t ||||	|
||||||||||frPtj||||	|
||||||||||d}nd }| j|I d H | _g }|rt|s|f}|D ]}|| j|I d H  qt	j
j| j|pd||d||pd d| _d S )N)joinleaveinvitebanunbanZkickZunkickpromotedemoteinfosettingspinnededitdelete
group_callrF   r   )r   min_idmax_idrT   events_filteradmins)anyr   ZChannelAdminLogEventsFilterr$   r-   rz   r   Zis_list_likerx   r	   rd   ZGetAdminLogRequestrequest)r#   rz   r   rM   r   r   r   r   r   restrict
unrestrictr   r   r   r   r   r   r   r   r   r   r   Z
admin_listZadminr)   r)   r*   r}      sX                     
     z_AdminLogIter._initc                    s   t | jt| j_| | jI d H }dd t|j|j	D }t dd |j
D dd| j_|j
D ]x}t|jtjr|jj| j|| j |jj| j|| j n$t|jtjr|jj| j|| j | jt|| q^t|j
| jjk rdS d S )Nc                 S   s   i | ]}t ||qS r)   )r   Zget_peer_idrY   xr)   r)   r*   r[     s    z2_AdminLogIter._load_next_chunk.<locals>.<dictcomp>c                 s   s   | ]}|j V  qd S r7   rV   )rY   er)   r)   r*   	<genexpr>  s     z1_AdminLogIter._load_next_chunk.<locals>.<genexpr>r   )defaultT)r~   left_MAX_ADMIN_LOG_CHUNK_SIZEr   rT   r$   	itertoolschainrq   chatseventsr   r\   r&   r   Z%ChannelAdminLogEventActionEditMessageZprev_messageZ_finish_initrz   Znew_messageZ'ChannelAdminLogEventActionDeleteMessagemessagerw   rx   r
   ZAdminLogEventrp   )r#   rentitiesZevr)   r)   r*   r     s>    
      z_AdminLogIter._load_next_chunkNr   r)   r)   r)   r*   r      s   !r   c                   @   s   e Zd Zdd Zdd ZdS )_ProfilePhotoIterc                    s   | j |I d H }t|}|tjjkr@tjj|||dd| _	n(tj
j|dt d d d|d|ddd| _	| jdkrd| j	_|  | j	I d H }t|tjjrt|j| _n*t|tj
jrt|j
| _nt|dd | _d S )Nr   )rS   r   rT   rF   r   )rt   r   rR   Zmin_dateZmax_date	offset_id
add_offsetrT   r   r   rU   r   )r$   r-   r   r_   r`   USERr	   photosZGetUserPhotosRequestr   r.   ZSearchRequestr   ZInputMessagesFilterChatPhotosrT   r\   Photosrp   r>   MessagesrI   )r#   rz   rS   r   r{   resultr)   r)   r*   r}   /  s<    


z_ProfilePhotoIter._initc                    s  t | jt| j_| | jI d H }t|tjj	rT|j| _
t| j
| _t| j
| _nVt|tjjrdd |jD | _
t| j
| _t| j
| _nt|tjjr|j| _
|j| _t| j
| jjk rt| j
| _n| j jt|j7  _nt|dd | _d  t|tjjrL| tj| jjI d H }|jj}t|tjrL| j
| |j | j
 fdd|jD  t|j| jjk rt| j
| _n |jrd| j_|jd j| j_d S )Nc                 S   s"   g | ]}t |jtjr|jjqS r)   )r\   r&   r   MessageActionChatEditPhotor   r   r)   r)   r*   
<listcomp>^  s    z6_ProfilePhotoIter._load_next_chunk.<locals>.<listcomp>r   c                 3   s2   | ]*}t |jtjr|jjj kr|jjV  qd S r7   )r\   r&   r   r   r   rW   r   Zseen_idr)   r*   r   ~  s   z5_ProfilePhotoIter._load_next_chunk.<locals>.<genexpr>r   ) r~   r   _MAX_PROFILE_PHOTO_CHUNK_SIZEr   rT   r$   r\   r   r   r   rw   rp   r>   r.   r   ZPhotosSlicer   rS   rI   ZChannelMessagesr	   rd   re   rt   rf   Z
chat_photoZPhotorx   rW   extendr   r   )r#   r   rQ   r   r)   r   r*   r   U  s@    	z"_ProfilePhotoIter._load_next_chunkNr   r)   r)   r)   r*   r   .  s   &r   c                   @   s  e Zd Zd:ddddddeedeedd	d
ZdddddZe	
ee_d;ddddddddddddddddddddddeeeedeeeeeeeeeeeeeeeedddZdddddZe	
ee_d<dddddeeeedddZdddddZe	
ee_dddddd eed!d"d#d$Zddddddddddddd%dddeeeeeeeeeeeeejd&d'd(Zd=ddddddddddddd)ddd*d+eeeeeeeeeeeeejd,d-d.Zddd*d/d0d1Zd>dddd2d3d4d5Zd?ddd6d7d8d9ZdS )@ChatMethodsNrF   F)rM   rR   
aggressiver   zhints.EntityLikez#types.TypeChannelParticipantsFilter)r#   rz   rT   rM   rR   r   returnc                C   s   t | ||||dS )as  
        Iterator over the participants belonging to the specified chat.

        The order is unspecified.

        Arguments
            entity (`entity`):
                The entity from which to retrieve the participants list.

            limit (`int`):
                Limits amount of participants fetched.

            search (`str`, optional):
                Look for participants with this string in name/username.

            filter (:tl:`ChannelParticipantsFilter`, optional):
                The filter to be used, if you want e.g. only admins
                Note that you might not have permissions for some filter.
                This has no effect for normal chats or users.

                .. note::

                    The filter :tl:`ChannelParticipantsBanned` will return
                    *restricted* users. If you want *banned* users you should
                    use :tl:`ChannelParticipantsKicked` instead.

            aggressive (`bool`, optional):
                Does nothing. This is kept for backwards-compatibility.

                There have been several changes to Telegram's API that limits
                the amount of members that can be retrieved, and this was a
                hack that no longer works.

        Yields
            The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
            with an additional ``.participant`` attribute which is the
            matched :tl:`ChannelParticipant` type for channels/megagroups
            or :tl:`ChatParticipants` for normal chats.

        Example
            .. code-block:: python

                # Show all user IDs in a chat
                async for user in client.iter_participants(chat):
                    print(user.id)

                # Search by name
                async for user in client.iter_participants(chat, search='name'):
                    print(user.username)

                # Filter by admins
                from telethon.tl.types import ChannelParticipantsAdmins
                async for user in client.iter_participants(chat, filter=ChannelParticipantsAdmins):
                    print(user.first_name)
        )rz   rR   rM   )rE   )r#   rz   rT   rM   rR   r   r)   r)   r*   iter_participants  s    ?zChatMethods.iter_participantszhints.TotalList)r#   r   c                    s   | j || I dH S )a  
        Same as `iter_participants()`, but returns a
        `TotalList <telethon.helpers.TotalList>` instead.

        Example
            .. code-block:: python

                users = await client.get_participants(chat)
                print(users[0].first_name)

                for user in users:
                    if user.username is not None:
                        print(user.username)
        N)r   collectr#   r5   kwargsr)   r)   r*   get_participants  s    zChatMethods.get_participantsr   )r   r   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   zhints.EntitiesLike)r#   rz   rT   r   r   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   c                C   s4   t | |||||||||	|
|||||||||||dS )a  
        Iterator over the admin log for the specified channel.

        The default order is from the most recent event to to the oldest.

        Note that you must be an administrator of it to use this method.

        If none of the filters are present (i.e. they all are `None`),
        *all* event types will be returned. If at least one of them is
        `True`, only those that are true will be returned.

        Arguments
            entity (`entity`):
                The channel entity from which to get its admin log.

            limit (`int` | `None`, optional):
                Number of events to be retrieved.

                The limit may also be `None`, which would eventually return
                the whole history.

            max_id (`int`):
                All the events with a higher (newer) ID or equal to this will
                be excluded.

            min_id (`int`):
                All the events with a lower (older) ID or equal to this will
                be excluded.

            search (`str`):
                The string to be used as a search query.

            admins (`entity` | `list`):
                If present, the events will be filtered by these admins
                (or single admin) and only those caused by them will be
                returned.

            join (`bool`):
                If `True`, events for when a user joined will be returned.

            leave (`bool`):
                If `True`, events for when a user leaves will be returned.

            invite (`bool`):
                If `True`, events for when a user joins through an invite
                link will be returned.

            restrict (`bool`):
                If `True`, events with partial restrictions will be
                returned. This is what the API calls "ban".

            unrestrict (`bool`):
                If `True`, events removing restrictions will be returned.
                This is what the API calls "unban".

            ban (`bool`):
                If `True`, events applying or removing all restrictions will
                be returned. This is what the API calls "kick" (restricting
                all permissions removed is a ban, which kicks the user).

            unban (`bool`):
                If `True`, events removing all restrictions will be
                returned. This is what the API calls "unkick".

            promote (`bool`):
                If `True`, events with admin promotions will be returned.

            demote (`bool`):
                If `True`, events with admin demotions will be returned.

            info (`bool`):
                If `True`, events changing the group info will be returned.

            settings (`bool`):
                If `True`, events changing the group settings will be
                returned.

            pinned (`bool`):
                If `True`, events of new pinned messages will be returned.

            edit (`bool`):
                If `True`, events of message edits will be returned.

            delete (`bool`):
                If `True`, events of message deletions will be returned.

            group_call (`bool`):
                If `True`, events related to group calls will be returned.

        Yields
            Instances of `AdminLogEvent <telethon.tl.custom.adminlogevent.AdminLogEvent>`.

        Example
            .. code-block:: python

                async for event in client.iter_admin_log(channel):
                    if event.changed_title:
                        print('The title changed from', event.old, 'to', event.new)
        )rz   r   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   )r#   rz   rT   r   r   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r)   r*   iter_admin_log  s0    {zChatMethods.iter_admin_logc                    s   | j || I dH S )a  
        Same as `iter_admin_log()`, but returns a ``list`` instead.

        Example
            .. code-block:: python

                # Get a list of deleted message events which said "heck"
                events = await client.get_admin_log(channel, search='heck', delete=True)

                # Print the old message before it was deleted
                print(events[0].old)
        N)r   r   r   r)   r)   r*   get_admin_log  s    zChatMethods.get_admin_log)rS   r   )r#   rz   rT   rS   r   r   c                C   s   t | ||||dS )a  
        Iterator over a user's profile photos or a chat's photos.

        The order is from the most recent photo to the oldest.

        Arguments
            entity (`entity`):
                The entity from which to get the profile or chat photos.

            limit (`int` | `None`, optional):
                Number of photos to be retrieved.

                The limit may also be `None`, which would eventually all
                the photos that are still available.

            offset (`int`):
                How many photos should be skipped before returning the first one.

            max_id (`int`):
                The maximum ID allowed when fetching photos.

        Yields
            Instances of :tl:`Photo`.

        Example
            .. code-block:: python

                # Download all the profile photos of some user
                async for photo in client.iter_profile_photos(user):
                    await client.download_media(photo)
        )rz   rS   r   )r   )r#   rz   rT   rS   r   r)   r)   r*   iter_profile_photos  s    &zChatMethods.iter_profile_photosc                    s   | j || I dH S )a  
        Same as `iter_profile_photos()`, but returns a
        `TotalList <telethon.helpers.TotalList>` instead.

        Example
            .. code-block:: python

                # Get the photos of a channel
                photos = await client.get_profile_photos(channel)

                # Download the oldest photo
                await client.download_media(photos[-1])
        N)r   r   r   r)   r)   r*   get_profile_photos  s    zChatMethods.get_profile_photos   Tr'   r(   z.typing.Union[str, types.TypeSendMessageAction]z+typing.Union[_ChatAction, typing.Coroutine])r#   rz   r&   r'   r(   r   c                C   s   t |trDztj|  }W q| tk
r@   td|dY q|X n8t |tj	rZ|j
dkr|t |trntdntd|t |tjr| tj|t S t| ||||dS )a  
        Returns a context-manager object to represent a "chat action".

        Chat actions indicate things like "user is typing", "user is
        uploading a photo", etc.

        If the action is ``'cancel'``, you should just ``await`` the result,
        since it makes no sense to use a context-manager for it.

        See the example below for intended usage.

        Arguments
            entity (`entity`):
                The entity where the action should be showed in.

            action (`str` | :tl:`SendMessageAction`):
                The action to show. You can either pass a instance of
                :tl:`SendMessageAction` or better, a string used while:

                * ``'typing'``: typing a text message.
                * ``'contact'``: choosing a contact.
                * ``'game'``: playing a game.
                * ``'location'``: choosing a geo location.
                * ``'sticker'``: choosing a sticker.
                * ``'record-audio'``: recording a voice note.
                  You may use ``'record-voice'`` as alias.
                * ``'record-round'``: recording a round video.
                * ``'record-video'``: recording a normal video.
                * ``'audio'``: sending an audio file (voice note or song).
                  You may use ``'voice'`` and ``'song'`` as aliases.
                * ``'round'``: uploading a round video.
                * ``'video'``: uploading a video file.
                * ``'photo'``: uploading a photo.
                * ``'document'``: uploading a document file.
                  You may use ``'file'`` as alias.
                * ``'cancel'``: cancel any pending action in this chat.

                Invalid strings will raise a ``ValueError``.

            delay (`int` | `float`):
                The delay, in seconds, to wait between sending actions.
                For example, if the delay is 5 and it takes 7 seconds to
                do something, three requests will be made at 0s, 5s, and
                7s to cancel the action.

            auto_cancel (`bool`):
                Whether the action should be cancelled once the context
                manager exists or not. The default is `True`, since
                you don't want progress to be shown when it has already
                completed.

        Returns
            Either a context-manager object or a coroutine.

        Example
            .. code-block:: python

                # Type for 2 seconds, then send a message
                async with client.action(chat, 'typing'):
                    await asyncio.sleep(2)
                    await client.send_message(chat, 'Hello world! I type slow ^^')

                # Cancel any previous action
                await client.action(chat, 'cancel')

                # Upload a document, showing its progress (most clients ignore this)
                async with client.action(chat, 'document') as action:
                    await client.send_file(chat, zip_file, progress_callback=action.progress)
        zNo such action "{}"Ni!̲ z(You must pass an instance, not the classzCannot use {} as actionr   )r\   strr   rB   lowerKeyError
ValueErrorformatr   ZTLObjectZSUBCLASS_OF_IDr]   r:   r	   r.   r/   )r#   rz   r&   r'   r(   r)   r)   r*   r&     s2    L



     zChatMethods.action)change_infopost_messagesedit_messagesdelete_messages	ban_usersinvite_userspin_messages
add_adminsmanage_call	anonymousis_admintitle)r#   rz   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   c             	      s  |  |I dH }|  |I dH }d}t|}|tjjkr|sB|r|j| jkrl| |I dH }|j| j|j< | j|j rd}d}t	 | t
jj||tjf  fdd|D |pddI dH S |tjjkr dkrtdd |D  | t
jj|j| d	I dH S td
dS )a  
        Edits admin permissions for someone in a chat.

        Raises an error if a wrong combination of rights are given
        (e.g. you don't have enough permissions to grant one).

        Unless otherwise stated, permissions will work in channels and megagroups.

        Arguments
            entity (`entity`):
                The channel, megagroup or chat where the promotion should happen.

            user (`entity`):
                The user to be promoted.

            change_info (`bool`, optional):
                Whether the user will be able to change info.

            post_messages (`bool`, optional):
                Whether the user will be able to post in the channel.
                This will only work in broadcast channels.

            edit_messages (`bool`, optional):
                Whether the user will be able to edit messages in the channel.
                This will only work in broadcast channels.

            delete_messages (`bool`, optional):
                Whether the user will be able to delete messages.

            ban_users (`bool`, optional):
                Whether the user will be able to ban users.

            invite_users (`bool`, optional):
                Whether the user will be able to invite users. Needs some testing.

            pin_messages (`bool`, optional):
                Whether the user will be able to pin messages.

            add_admins (`bool`, optional):
                Whether the user will be able to add admins.

            manage_call (`bool`, optional):
                Whether the user will be able to manage group calls.

            anonymous (`bool`, optional):
                Whether the user will remain anonymous when sending messages.
                The sender of the anonymous messages becomes the group itself.

                .. note::

                    Users may be able to identify the anonymous admin by its
                    custom title, so additional care is needed when using both
                    ``anonymous`` and custom titles. For example, if multiple
                    anonymous admins share the same title, users won't be able
                    to distinguish them.

            is_admin (`bool`, optional):
                Whether the user will be an admin in the chat.
                This will only work in small group chats.
                Whether the user will be an admin in the chat. This is the
                only permission available in small group chats, and when
                used in megagroups, all non-explicitly set permissions will
                have this value.

                Essentially, only passing ``is_admin=True`` will grant all
                permissions, but you can still disable those you need.

            title (`str`, optional):
                The custom title (also known as "rank") to show for this admin.
                This text will be shown instead of the "admin" badge.
                This will only work in channels and megagroups.

                When left unspecified or empty, the default localized "admin"
                badge will be shown.

        Returns
            The resulting :tl:`Updates` object.

        Example
            .. code-block:: python

                # Allowing `user` to pin messages in `chat`
                await client.edit_admin(chat, user, pin_messages=True)

                # Granting all permissions except for `add_admins`
                await client.edit_admin(chat, user, is_admin=True, add_admins=False)
        N)
r   r   r   r   r   r   r   r   r   r   c                    s&   i | ]}|| d k	r| n qS r7   r)   )rY   namer   Zpermsr)   r*   r[     s    z*ChatMethods.edit_admin.<locals>.<dictcomp>rF   )Zrankc                 s   s   | ]}t  | V  qd S r7   )localsr   r)   r)   r*   r     s     z)ChatMethods.edit_admin.<locals>.<genexpr>)r   z4You can only edit permissions in groups and channels)r-   r   r_   r`   ra   Z
channel_idZ_megagroup_cachery   Z	megagroupr   r	   rd   ZEditAdminRequestr   ZChatAdminRightsrl   r   r.   ZEditChatAdminRequestrn   r   )r#   rz   rZ   r   r   r   r   r   r   r   r   r   r   r   r   Z
perm_namesr{   Zfull_entityr)   r   r*   
edit_admin9  s:    h
  zChatMethods.edit_admin)view_messagessend_messages
send_mediasend_stickers	send_gifs
send_gamessend_inlineembed_link_previews
send_pollsr   r   r   z!typing.Optional[hints.EntityLike]zhints.DateLike)r#   rz   rZ   
until_dater   r   r   r   r   r   r   r   r   r   r   r   r   c                   s   |  |I dH }t|}|tjjkr.tdtj|| | | | | |	 |
 | | | | | d}|dkr| tj	j
||dI dH S |  |I dH }| tjj|||dI dH S )a  
        Edits user restrictions in a chat.

        Set an argument to `False` to apply a restriction (i.e. remove
        the permission), or omit them to use the default `True` (i.e.
        don't apply a restriction).

        Raises an error if a wrong combination of rights are given
        (e.g. you don't have enough permissions to revoke one).

        By default, each boolean argument is `True`, meaning that it
        is true that the user has access to the default permission
        and may be able to make use of it.

        If you set an argument to `False`, then a restriction is applied
        regardless of the default permissions.

        It is important to note that `True` does *not* mean grant, only
        "don't restrict", and this is where the default permissions come
        in. A user may have not been revoked the ``pin_messages`` permission
        (it is `True`) but they won't be able to use it if the default
        permissions don't allow it either.

        Arguments
            entity (`entity`):
                The channel or megagroup where the restriction should happen.

            user (`entity`, optional):
                If specified, the permission will be changed for the specific user.
                If left as `None`, the default chat permissions will be updated.

            until_date (`DateLike`, optional):
                When the user will be unbanned.

                If the due date or duration is longer than 366 days or shorter than
                30 seconds, the ban will be forever. Defaults to ``0`` (ban forever).

            view_messages (`bool`, optional):
                Whether the user is able to view messages or not.
                Forbidding someone from viewing messages equals to banning them.
                This will only work if ``user`` is set.

            send_messages (`bool`, optional):
                Whether the user is able to send messages or not.

            send_media (`bool`, optional):
                Whether the user is able to send media or not.

            send_stickers (`bool`, optional):
                Whether the user is able to send stickers or not.

            send_gifs (`bool`, optional):
                Whether the user is able to send animated gifs or not.

            send_games (`bool`, optional):
                Whether the user is able to send games or not.

            send_inline (`bool`, optional):
                Whether the user is able to use inline bots or not.

            embed_link_previews (`bool`, optional):
                Whether the user is able to enable the link preview in the
                messages they send. Note that the user will still be able to
                send messages with links if this permission is removed, but
                these links won't display a link preview.

            send_polls (`bool`, optional):
                Whether the user is able to send polls or not.

            change_info (`bool`, optional):
                Whether the user is able to change info or not.

            invite_users (`bool`, optional):
                Whether the user is able to invite other users or not.

            pin_messages (`bool`, optional):
                Whether the user is able to pin messages or not.

        Returns
            The resulting :tl:`Updates` object.

        Example
            .. code-block:: python

                from datetime import timedelta

                # Banning `user` from `chat` for 1 minute
                await client.edit_permissions(chat, user, timedelta(minutes=1),
                                              view_messages=False)

                # Banning `user` from `chat` forever
                await client.edit_permissions(chat, user, view_messages=False)

                # Kicking someone (ban + un-ban)
                await client.edit_permissions(chat, user, view_messages=False)
                await client.edit_permissions(chat, user)
        Nz.You must pass either a channel or a supergroup)r   r   r   r   r   r   r   r   Zembed_linksr   r   r   r   )rt   banned_rightsrQ   rv   r   )r-   r   r_   r`   ra   r   r   ChatBannedRightsr	   r.   Z"EditChatDefaultBannedRightsRequestrd   EditBannedRequest)r#   rz   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r{   Zrightsr)   r)   r*   edit_permissions  s<    s
zChatMethods.edit_permissions)r#   rz   rZ   c                    s   |  |I dH }|  |I dH }t|}|tjjkrR| tj|j|I dH }n|tjj	krt
|tjr| tj|I dH }q| tjj||tjddddI dH }tdI dH  | tjj||tjdddI dH  ntd| d||S )a  
        Kicks a user from a chat.

        Kicking yourself (``'me'``) will result in leaving the chat.

        .. note::

            Attempting to kick someone who was banned will remove their
            restrictions (and thus unbanning them), since kicking is just
            ban + unban.

        Arguments
            entity (`entity`):
                The channel or chat where the user should be kicked from.

            user (`entity`, optional):
                The user to kick.

        Returns
            Returns the service `Message <telethon.tl.custom.message.Message>`
            produced about a user being kicked, if any.

        Example
            .. code-block:: python

                # Kick some user from some chat, and deleting the service message
                msg = await client.kick_participant(chat, user)
                await msg.delete()

                # Leaving chat
                await client.kick_participant(chat, 'me')
        NT)r   r   r   g      ?)r   (You must pass either a channel or a chat)r-   r   r_   r`   rl   r	   r.   ZDeleteChatUserRequestrn   ra   r\   r   InputPeerSelfrd   ZLeaveChannelRequestr   r   r3   r8   r   Z_get_response_message)r#   rz   rZ   r{   respr)   r)   r*   kick_participantd  s0    %
 
zChatMethods.kick_participantz.typing.Optional[custom.ParticipantPermissions])r#   rz   rZ   r   c                    sX  |  |I dH }|snt|tjr8| tj|I dH }n*t|tjr^| tj	|j
I dH }ndS |jd jS | |I dH }| |I dH }t|tjjkr| tj||I dH }t|jdS t|tjjkrL| tj	|jI dH }t|tjr| jddI dH }|jjjD ]$}|j|jkrt|d  S qtdtddS )a  
        Fetches the permissions of a user in a specific chat or channel or
        get Default Restricted Rights of Chat or Channel.

        .. note::

            This request has to fetch the entire chat for small group chats,
            which can get somewhat expensive, so use of a cache is advised.

        Arguments
            entity (`entity`):
                The channel or chat the user is participant of.

            user (`entity`, optional):
                Target user.

        Returns
            A `ParticipantPermissions <telethon.tl.custom.participantpermissions.ParticipantPermissions>`
            instance. Refer to its documentation to see what properties are
            available.

        Example
            .. code-block:: python

                permissions = await client.get_permissions(chat, user)
                if permissions.is_admin:
                    # do something

                # Get Banned Permissions of Chat
                await client.get_permissions(chat)
        Nr   FT)Z
input_peerr   ) ry   r\   r   ZChannelr	   rd   re   ZChatr.   rm   rW   r   Zdefault_banned_rightsr-   r   r_   r`   ra   ZGetParticipantRequestr
   ZParticipantPermissionsrv   rl   rn   r   Zget_merf   ro   ru   r   ZUserNotParticipantErrorr   )r#   rz   rZ   ZFullChatrv   r%   r)   r)   r*   get_permissions  s6    $
zChatMethods.get_permissionsz typing.Union[int, types.Message])r#   rz   r   c                    sp  |  |I dH }t|tjjkr*tdt|}|dk	rztj	
||}| |I dH W S  tjk
r } z
|j}W 5 d}~X Y nX nztj	|}| |I dH W S  tjk
r } z
|j}W 5 d}~X Y nf tjk
r2   tj	|}z| |I dH W  Y S  tjk
r, } z
|j}W 5 d}~X Y nX Y nX | |I dH }z||I dH W S | |I dH  X dS )a9  
        Retrieves statistics from the given megagroup or broadcast channel.

        Note that some restrictions apply before being able to fetch statistics,
        in particular the channel must have enough members (for megagroups, this
        requires `at least 500 members`_).

        Arguments
            entity (`entity`):
                The channel from which to get statistics.

            message (`int` | ``Message``, optional):
                The message ID from which to get statistics, if your goal is
                to obtain the statistics of a single message.

        Raises
            If the given entity is not a channel (broadcast or megagroup),
            a `TypeError` is raised.

            If there are not enough members (poorly named) errors such as
            ``telethon.errors.ChatAdminRequiredError`` will appear.

        Returns
            If both ``entity`` and ``message`` were provided, returns
            :tl:`MessageStats`. Otherwise, either :tl:`BroadcastStats` or
            :tl:`MegagroupStats`, depending on whether the input belonged to a
            broadcast channel or megagroup.

        Example
            .. code-block:: python

                # Some megagroup or channel username or ID to fetch
                channel = -100123
                stats = await client.get_stats(channel)
                print('Stats from', stats.period.min_date, 'to', stats.period.max_date, ':')
                print(stats.stringify())

        .. _`at least 500 members`: https://telegram.org/blog/profile-videos-people-nearby-and-more
        NzYou must pass a channel entity)r-   r   r_   r`   ra   	TypeErrorr   Zget_message_idr	   statsZGetMessageStatsRequestr   ZStatsMigrateErrordcZGetBroadcastStatsRequestZBroadcastRequiredErrorZGetMegagroupStatsRequestZ_borrow_exported_senderZ_return_exported_sendersend)r#   rz   r   reqr   r   Zsenderr)   r)   r*   	get_stats  s2    ,
zChatMethods.get_stats)N)N)N)NN)N)N)r?   r@   rA   floatr   boolrE   r   r   inspect	signature__signature__intr   r   r   r   r   r   r&   r   ZUpdatesr   r   r   r   r   r)   r)   r)   r*   r     sd    H     / f      E G r   )r3   r   r   stringr   rF   r   r   r   r   Zrequestiterr   tlr   r	   r
   TYPE_CHECKINGZtelegramclientr   rk   r   r   r   rE   r   r   r   r)   r)   r)   r*   <module>   s$   P =]