a
    f’i;9  ã                   @   s   d Z ddlZddlZddlZddlZ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 ddlmZ G dd„ dejƒZe e¡Zd)dd	„Zd
d„ Zdd„ Zdd„ Zddœdd„Zdd„ Zd*dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ ZG d#d$„ d$e ƒZ!G d%d&„ d&ej"ƒZ#d'd(„ Z$dS )+z6Various helpers not related to the Telegram API itselfé    N)ÚPath)Úsha1c                   @   s   e Zd ZdZdZdZdS )Ú_EntityTyper   é   é   N)Ú__name__Ú
__module__Ú__qualname__ÚUSERÚCHATÚCHANNEL© r   r   úE/home/ec2-user/.local/lib/python3.9/site-packages/telethon/helpers.pyr      s   r   Tc                 C   s   t jt d¡| ddS )zEGenerates a random long integer (8 bytes), which is optionally signedé   Úlittle)ÚsignedÚ	byteorder)ÚintÚ
from_bytesÚosÚurandom©r   r   r   r   Úgenerate_random_long   s    r   c                 C   s"   t j | ¡}|rt j|dd dS )z(Ensures that the parent directory existsT)Úexist_okN)r   ÚpathÚdirnameÚmakedirs)Ú	file_pathÚparentr   r   r   Úensure_parent_dir_exists    s    r   c                 C   s   d  dd„ | D ƒ¡S )NÚ c              
   s   sP   | ]H}d t |ƒ  krdkrDn n"d dd„ t d| d¡¡D ƒ¡n|V  qdS )i   iÿÿ r    c                 s   s   | ]}t |ƒV  qd S ©N)Úchr)Ú.0Úyr   r   r   Ú	<genexpr>+   ó    z*add_surrogate.<locals>.<genexpr>.<genexpr>z<HHzutf-16leN)ÚordÚjoinÚstructÚunpackÚencode©r#   Úxr   r   r   r%   (   s
   
ÿÿ,z add_surrogate.<locals>.<genexpr>)r(   ©Útextr   r   r   Úadd_surrogate'   s    
ür0   c                 C   s   |   dd¡ d¡S )Nzutf-16Úsurrogatepass)r+   Údecoder.   r   r   r   Údel_surrogate0   s    r3   )Úlengthc                C   sh   |du rt | ƒ}d|  k o&t | ƒk n  ofd| |d    koFdkn  ofd| |   kobdkS   S )zS
    `True` if ``index`` is within a surrogate (before and after it, not at!).
    Nr   u   í €u   í¯¿u   í¿¿)Úlen)r/   Úindexr4   r   r   r   Úwithin_surrogate4   s    ÿýr7   c                 C   sè   |s|   ¡ S t| ƒ}|  ¡ } |t| ƒ }|  ¡ } t| ƒ}ttt|ƒƒƒD ]š}|| }|jdkrf||= qH|j|j |krª|j|kr| j|8  _q²|j|j | |_d|_n||= qH|j|j |krÄqH|j|krÖ||= qH||j |_qH| S )zý
    Strips whitespace from the given surrogated text modifying the provided
    entities, also removing any empty (0-length) entities.

    This assumes that the length of entities is greater or equal to 0, and
    that no entity is out of bounds.
    r   )Ústripr5   ÚlstripÚrstripÚreversedÚranger4   Úoffset)r/   ÚentitiesZlen_oriZleft_offsetZ	len_finalÚiÚer   r   r   Ú
strip_textB   s2    

	

rA   c                 c   s<   |r| du s| dk s| d7 } d}|| kr8|d7 }|V  q dS )z¿
    Generates an integer sequence starting from 1. If `retries` is
    not a zero or a positive integer value, the sequence will be
    infinite, otherwise it will end at `retries + 1`.
    Nr   r   r   )ÚretriesZforce_retryÚattemptr   r   r   Úretry_rangeŒ   s    	rD   c                 Ã   s   t  | ¡r| I d H S | S d S r!   )ÚinspectÚisawaitable)Úvaluer   r   r   Ú_maybe_awaitŸ   s    

rH   c                 Ë   s¼   |  ¡ D ]®\}}|sq| ¡  z|I dH  W q tjy@   Y q tyP   Y q ty } z*|jdkr||  d|t|ƒ|¡ W Y d}~qd}~0  t	y´   |  d|t|ƒ|¡ Y q0 qdS )zL
    Helper to cancel one or more tasks gracefully, logging exceptions.
    N)z"yield from wasn't used with futurez4Unhandled exception from %s after cancelling %s (%s))
ÚitemsÚcancelÚasyncioÚCancelledErrorÚRuntimeErrorÚAssertionErrorÚargsÚ	exceptionÚtypeÚ	Exception)ÚlogÚtasksÚnameÚtaskr@   r   r   r   Ú_cancel¦   s&    

ÿ
ÿrW   c                 C   s8   t | dƒr| j}n| jj}| ¡ r*tdƒ‚| |  ¡ ¡S )za
    Helps to cut boilerplate on async context
    managers that offer synchronous variants.
    Úloopz[You must use "async with" if the event loop is running (i.e. you are inside an "async def"))ÚhasattrrX   Ú_clientÚ
is_runningrM   Úrun_until_completeÚ
__aenter__)ÚselfrX   r   r   r   Ú_sync_enterË   s    
ÿr_   c                 G   s*   t | dƒr| j}n| jj}| | j|Ž ¡S )NrX   )rY   rX   rZ   r\   Ú	__aexit__)r^   rO   rX   r   r   r   Ú
_sync_exitÞ   s    
ra   c                 C   s   z| j dvrtd | ¡ƒ‚W n  ty<   td | ¡ƒ‚Y n0 | jj}d|v rTtjS d|v rbtjS d|v rptj	S d|v r~tjS td | ¡ƒ‚d S )N)i‡VÔl   ¶9 l   F?ÓL iýò@iwy¡-l   ”]^ i¹aFl   —&4) z {} does not have any entity typez2{} is not a TLObject, cannot determine entity typeZUserZChatZChannelZSelf)
ZSUBCLASS_OF_IDÚ	TypeErrorÚformatÚAttributeErrorÚ	__class__r   r   r
   r   r   )ÚentityrU   r   r   r   Ú_entity_typeç   s    

rg   c                 C   s„   | j dddd} |j dddd}t||  ƒ ¡ }t| | ƒ ¡ }t|| ƒ ¡ }||dd…  }|dd… | |dd	…  }||fS )
z7Generates the key data corresponding to the given nonceé   r   Tr   é    Né   é   é   )Úto_bytesr   Údigest)Zserver_nonceZ	new_nonceZhash1Zhash2Zhash3ÚkeyZivr   r   r   Úgenerate_key_data_from_nonce  s    rp   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )Ú	TotalListaµ  
    A list with an extra `total` property, which may not match its `len`
    since the total represents the total amount of items *available*
    somewhere else, not the items *in this list*.

    Examples:

        .. code-block:: python

            # Telethon returns these lists in some cases (for example,
            # only when a chunk is returned, but the "total" count
            # is available).
            result = await client.get_messages(chat, limit=10)

            print(result.total)  # large number
            print(len(result))  # 10
            print(result[0])  # latest message

            for x in result:  # show the 10 messages
                print(x.text)

    c                    s   t ƒ j|i |¤Ž d| _d S )Nr   )ÚsuperÚ__init__Útotal©r^   rO   Úkwargs©re   r   r   rs   8  s    zTotalList.__init__c                 C   s   d  d dd„ | D ƒ¡| j¡S )Nú[{}, total={}]ú, c                 s   s   | ]}t |ƒV  qd S r!   )Ústrr,   r   r   r   r%   >  r&   z$TotalList.__str__.<locals>.<genexpr>©rc   r(   rt   ©r^   r   r   r   Ú__str__<  s    ÿzTotalList.__str__c                 C   s   d  d dd„ | D ƒ¡| j¡S )Nrx   ry   c                 s   s   | ]}t |ƒV  qd S r!   )Úreprr,   r   r   r   r%   B  r&   z%TotalList.__repr__.<locals>.<genexpr>r{   r|   r   r   r   Ú__repr__@  s    ÿzTotalList.__repr__)r   r   r	   Ú__doc__rs   r}   r   Ú__classcell__r   r   rw   r   rq   !  s   rq   c                   @   sÆ   e Zd ZdZddœdd„Zdd„ Zdd	„ Zed
d„ ƒZedd„ ƒZ	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ ZdS ).Ú_FileStreama:  
    Proxy around things that represent a file and need to be used as streams
    which may or not need to be closed.

    This will handle `pathlib.Path`, `str` paths, in-memory `bytes`, and
    anything IO-like (including `aiofiles`).

    It also provides access to the name and file size (also necessary).
    N)Ú	file_sizec                C   s8   t |tƒrt| ¡ ƒ}|| _d | _|| _d | _d | _d S r!   )	Ú
isinstancer   rz   ÚabsoluteÚ_fileÚ_nameÚ_sizeÚ_streamÚ_close_stream)r^   Úfilerƒ   r   r   r   rs   O  s    
z_FileStream.__init__c                 Ã   sˆ  t | jtƒrDtj | j¡| _tj | j¡| _t	| jdƒ| _
d| _| S t | jtƒrtt| jƒ| _t | j¡| _
d| _| S tt| jdd ƒƒsŽtdƒ‚t| jdd ƒ| _| j| _
d| _| jd u r„tt| jdd ƒƒràt| j ¡ ƒI d H }nd}|rJt| j ¡ ƒI d H }t| j dtj¡ƒI d H  t| j ¡ ƒI d H | _t| j |tj¡ƒI d H  n:t d	¡ t| j ¡ ƒI d H }t|ƒ| _t |¡| _
d| _| S )
NÚrbTÚreadz,file description should have a `read` methodrU   FÚseekabler   zRCould not determine file size beforehand so the entire file will be read in-memory)r„   r†   rz   r   r   Úbasenamer‡   Úgetsizerˆ   Úopenr‰   rŠ   Úbytesr5   ÚioÚBytesIOÚcallableÚgetattrrb   rH   rŽ   ÚtellÚseekÚSEEK_ENDÚSEEK_SETÚ_logÚwarningr   )r^   rŽ   ÚposÚdatar   r   r   r]   Y  sB    ÿ
z_FileStream.__aenter__c                 Ã   s$   | j r | jr t| j ¡ ƒI d H  d S r!   )rŠ   r‰   rH   Úclose)r^   Úexc_typeÚexc_valÚexc_tbr   r   r   r`   …  s    z_FileStream.__aexit__c                 C   s   | j S r!   )rˆ   r|   r   r   r   rƒ   ‰  s    z_FileStream.file_sizec                 C   s   | j S r!   )r‡   r|   r   r   r   rU     s    z_FileStream.namec                 O   s   | j j|i |¤ŽS r!   )r‰   r   ru   r   r   r   r   ’  r&   z_FileStream.readc                 O   s   | j j|i |¤ŽS r!   )r‰   Úreadintoru   r   r   r   r£   “  r&   z_FileStream.readintoc                 O   s   | j j|i |¤ŽS r!   )r‰   Úwriteru   r   r   r   r¤   ”  r&   z_FileStream.writec                 O   s   | j j|i |¤ŽS r!   )r‰   Úfilenoru   r   r   r   r¥   •  r&   z_FileStream.filenoc                 O   s   | j j|i |¤ŽS r!   )r‰   Úflushru   r   r   r   r¦   –  r&   z_FileStream.flushc                 O   s   | j j|i |¤ŽS r!   )r‰   Úisattyru   r   r   r   r§   —  r&   z_FileStream.isattyc                 O   s   | j j|i |¤ŽS r!   )r‰   Úreadableru   r   r   r   r¨   ˜  r&   z_FileStream.readablec                 O   s   | j j|i |¤ŽS r!   )r‰   Úreadlineru   r   r   r   r©   ™  r&   z_FileStream.readlinec                 O   s   | j j|i |¤ŽS r!   )r‰   Ú	readlinesru   r   r   r   rª   š  r&   z_FileStream.readlinesc                 O   s   | j j|i |¤ŽS r!   )r‰   r˜   ru   r   r   r   r˜   ›  r&   z_FileStream.seekc                 O   s   | j j|i |¤ŽS r!   )r‰   rŽ   ru   r   r   r   rŽ   œ  r&   z_FileStream.seekablec                 O   s   | j j|i |¤ŽS r!   )r‰   r—   ru   r   r   r   r—     r&   z_FileStream.tellc                 O   s   | j j|i |¤ŽS r!   )r‰   Útruncateru   r   r   r   r«   ž  r&   z_FileStream.truncatec                 O   s   | j j|i |¤ŽS r!   )r‰   Úwritableru   r   r   r   r¬   Ÿ  r&   z_FileStream.writablec                 O   s   | j j|i |¤ŽS r!   )r‰   Ú
writelinesru   r   r   r   r­      r&   z_FileStream.writelinesc                 O   s   d S r!   r   ru   r   r   r   rŸ   ¦  s    z_FileStream.close)r   r   r	   r€   rs   r]   r`   Úpropertyrƒ   rU   r   r£   r¤   r¥   r¦   r§   r¨   r©   rª   r˜   rŽ   r—   r«   r¬   r­   rŸ   r   r   r   r   r‚   E  s0   	
,

r‚   c                   C   sB   t jdkr6z
t ¡ W S  ty2   t ¡  ¡  Y S 0 nt ¡ S d S )N)é   é   )ÚsysÚversion_inforK   Úget_running_looprM   Úget_event_loop_policyÚget_event_loopr   r   r   r   r³   «  s    

r³   )T)T)%r€   rK   r“   Úenumr   r)   rE   ÚloggingÚ	functoolsr±   Úpathlibr   Úhashlibr   ÚEnumr   Ú	getLoggerr   r›   r   r   r0   r3   r7   rA   rD   rH   rW   r_   ra   rg   rp   Úlistrq   ÚIOBaser‚   r³   r   r   r   r   Ú<module>   s:   

	J
%	($f