B
    fd                 @   s  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mZ d dlmZ d dlmZ d dlmZ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 d dlZd d
l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' d dl&m(Z(m)Z)m*Z*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1m2Z2 d dl3m4Z4m5Z5 d dl6m7Z7m8Z8 d dl9m:Z: ddl;m<Z< ddl=m>Z>m?Z?m@Z@ ddlAmAZA ddlBmCZC ddlDmEZE eFeGZHG dd de/ZIG dd  d ZJdS )!    N)ThreadPoolExecutor)datetime	timedelta)sha256)import_module)StringIOBytesIO)	MimeTypes)Path)UnionListOptionalCallableAsyncGenerator)__version____license__)enums)raw)utils)aes)CDNFileHashMismatch)SessionPasswordNeededVolumeLocNotFoundChannelPrivate
BadRequest)Handler)Methods)AuthSession)FileStorageMemoryStorage)UserTermsOfService)ainput   )
Dispatcher)FileIdFileTypeThumbnailSource)
mime_types)Parser)MsgIdc                   s  e Zd ZdZde Ze  de  Z	e
  de  ZdZeejd jZedZede pndd ZeZd	Zd
Ze Zee e! ddee	eedddddddddeede"j#j$dde%j&defe'e(e)e'f e'e'e'e'e'e*e+e*e'e'e*e'e'e'e)e'e+de*e*e)e*e)d fddZ,dd Z-dd Z.dd Z/dd Z0dd Z1e2dddZ3e4d ddd Z5e6e(e7j8j2e7j8j9e7j8j:f  e*d!d"d#Z;d$d% Z<d&d' Z=d(d) Z>d*d+ Z?d6e@e)e)e)eAeBe4eCeDdf  d-d.d/ZEe'e4e' d0d1d2ZFe'e4e' d3d4d5ZG  ZHS )7Clienta  Pyrogram Client, the main means for interacting with Telegram.

    Parameters:
        name (``str``):
            A name for the client, e.g.: "my_account".

        api_id (``int`` | ``str``, *optional*):
            The *api_id* part of the Telegram API key, as integer or string.
            E.g.: 12345 or "12345".

        api_hash (``str``, *optional*):
            The *api_hash* part of the Telegram API key, as string.
            E.g.: "0123456789abcdef0123456789abcdef".

        app_version (``str``, *optional*):
            Application version.
            Defaults to "Pyrogram x.y.z".

        device_model (``str``, *optional*):
            Device model.
            Defaults to *platform.python_implementation() + " " + platform.python_version()*.

        system_version (``str``, *optional*):
            Operating System version.
            Defaults to *platform.system() + " " + platform.release()*.

        lang_code (``str``, *optional*):
            Code of the language used on the client, in ISO 639-1 standard.
            Defaults to "en".

        ipv6 (``bool``, *optional*):
            Pass True to connect to Telegram using IPv6.
            Defaults to False (IPv4).

        proxy (``dict``, *optional*):
            The Proxy settings as dict.
            E.g.: *dict(scheme="socks5", hostname="11.22.33.44", port=1234, username="user", password="pass")*.
            The *username* and *password* can be omitted if the proxy doesn't require authorization.

        test_mode (``bool``, *optional*):
            Enable or disable login to the test servers.
            Only applicable for new sessions and will be ignored in case previously created sessions are loaded.
            Defaults to False.

        bot_token (``str``, *optional*):
            Pass the Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
            Only applicable for new sessions.

        session_string (``str``, *optional*):
            Pass a session string to load the session in-memory.
            Implies ``in_memory=True``.

        in_memory (``bool``, *optional*):
            Pass True to start an in-memory session that will be discarded as soon as the client stops.
            In order to reconnect again using an in-memory session without having to login again, you can use
            :meth:`~pyrogram.Client.export_session_string` before stopping the client to get a session string you can
            pass to the ``session_string`` parameter.
            Defaults to False.

        phone_number (``str``, *optional*):
            Pass the phone number as string (with the Country Code prefix included) to avoid entering it manually.
            Only applicable for new sessions.

        phone_code (``str``, *optional*):
            Pass the phone code as string (for test numbers only) to avoid entering it manually.
            Only applicable for new sessions.

        password (``str``, *optional*):
            Pass the Two-Step Verification password as string (if required) to avoid entering it manually.
            Only applicable for new sessions.

        workers (``int``, *optional*):
            Number of maximum concurrent workers for handling incoming updates.
            Defaults to ``min(32, os.cpu_count() + 4)``.

        workdir (``str``, *optional*):
            Define a custom working directory.
            The working directory is the location in the filesystem where Pyrogram will store the session files.
            Defaults to the parent directory of the main script.

        plugins (``dict``, *optional*):
            Smart Plugins settings as dict, e.g.: *dict(root="plugins")*.

        parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
            Set the global parse mode of the client. By default, texts are parsed using both Markdown and HTML styles.
            You can combine both syntaxes together.

        no_updates (``bool``, *optional*):
            Pass True to disable incoming updates.
            When updates are disabled the client can't receive messages or other updates.
            Useful for batch programs that don't need to deal with updates.
            Defaults to False (updates enabled and received).

        takeout (``bool``, *optional*):
            Pass True to let the client use a takeout session instead of a normal one, implies *no_updates=True*.
            Useful for exporting Telegram data. Methods invoked inside a takeout session (such as get_chat_history,
            download_media, ...) are less prone to throw FloodWait exceptions.
            Only available for users, bots will ignore this parameter.
            Defaults to False (normal session).

        sleep_threshold (``int``, *optional*):
            Set a sleep threshold for flood wait exceptions happening globally in this client instance, below which any
            request that raises a flood wait will be automatically invoked again after sleeping for the required amount
            of time. Flood wait exceptions requiring higher waiting times will be raised.
            Defaults to 10 seconds.

        hide_password (``bool``, *optional*):
            Pass True to hide the password when typing it during the login.
            Defaults to False, because ``getpass`` (the library used) is known to be problematic in some
            terminal environments.

        max_concurrent_transmissions (``bool``, *optional*):
            Set the maximum amount of concurrent transmissions (uploads & downloads).
            A value that is too high may result in network related issues.
            Defaults to 1.
    z	Pyrogram  enr   zT^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:joinchat/|\+))([\w-]+)$       i,  r$   NFzenums.ParseMode)nameapi_idapi_hashapp_versiondevice_modelsystem_version	lang_codeipv6proxy	test_mode	bot_tokensession_string	in_memoryphone_number
phone_codepasswordworkersworkdirplugins
parse_mode
no_updatestakeoutsleep_thresholdhide_passwordmax_concurrent_transmissionsc                s  t    || _|rt|nd | _|| _|| _|| _|| _|	 | _
|| _|	| _|
| _|| _|| _|| _|| _|| _|| _|| _t|| _|| _|| _|| _|| _|| _|| _|| _t| jdd| _| jrt | j| j| _!n$| jrt | j| _!nt"| j| j| _!t#| | _$t%| _&t'| | _(d | _)i | _*t+, | _-t+.| j| _/t+.| j| _0d | _1d | _2d | _3d | _4d | _5t6d| _7d | _8t+9 | _:t;< | _=t+> | _?d S )Nr   )Zthread_name_prefixi'  )@super__init__r1   intr2   r3   r4   r5   r6   lowerr7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   r
   rB   rC   rD   rE   rF   rG   rH   rI   r   executorr    storager   r%   
dispatcherr+   Zrnd_idr*   parsersessionZmedia_sessionsasyncioLockZmedia_sessions_lock	SemaphoreZsave_file_semaphoreget_file_semaphoreZis_connectedZis_initializedZ
takeout_idZdisconnect_handlermeCacheZmessage_cacheZupdates_watchdog_taskEventupdates_watchdog_eventr   nowlast_update_timeZget_event_looploop)selfr1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   )	__class__ 3/tmp/pip-unpacked-wheel-rcokkf2l/pyrogram/client.pyrK      sd    








zClient.__init__c             C   s   |   S )N)start)r^   r`   r`   ra   	__enter__-  s    zClient.__enter__c             G   s&   y|    W n tk
r    Y nX d S )N)stopConnectionError)r^   argsr`   r`   ra   __exit__0  s    zClient.__exit__c                s   |   I d H S )N)rb   )r^   r`   r`   ra   
__aenter__6  s    zClient.__aenter__c                s,   y|   I d H  W n tk
r&   Y nX d S )N)rd   re   )r^   rf   r`   r`   ra   	__aexit__9  s    zClient.__aexit__c                st   xnyt | j | jI d H  W n t jk
r6   Y nX P t | j t	| jdkr| 
tjj I d H  qW d S )N)seconds)rS   wait_forrZ   waitUPDATES_WATCHDOG_INTERVALTimeoutErrorr   r[   r\   r   invoker   	functionsupdatesZGetState)r^   r`   r`   ra   updates_watchdog?  s    zClient.updates_watchdog)returnc                s  | j r| | j I d H S tdt d tdt d xy~| jsx<tdI d H }|sXqDtd| dI d H  }|dkrDP qDW d	|kr|| _ | |I d H S || _| | jI d H }W n8 t	k
r } zt|j
 d | _d | _ W d d }~X Y q:X P q:W tjjd
tjjdtjjdtjjdtjjdtjjdi}td||j   x| js\tdI d H | _y | | j|j| jI d H }W n t	k
r } zt|j
 d | _W d d }~X Y qD tk
r6 } zdt|j
 xRtd|  I d H  | js
td| jdI d H | _y| jstdI d H }|dkr|  I d H }td|  xtdI d H }y| |I d H S  t	k
r } zt|j
 W d d }~X Y n0 tk
r } zt |  W d d }~X Y nX qJW nd | _n| !| jI d H S W n4 t	k
r } zt|j
 d | _W d d }~X Y nX qW W d d }~X Y nX P qDW t"|t#rP|S xrtdI d H }	tdI d H }
y| $| j|j|	|
I d H }W n. t	k
r } zt|j
 W d d }~X Y nX P qRW t"|t%rtd|j& d  | '|j(I d H  |S )NzWelcome to Pyrogram (version )zaPyrogram is free software and comes with ABSOLUTELY NO WARRANTY. Licensed
under the terms of the z.
z!Enter phone number or bot token: zIs "z" correct? (y/N): y:zTelegram appSMSz
phone callzphone flash callzFragment SMSz
email codez(The confirmation code has been sent via zEnter confirmation code: zPassword hint: {}z#Enter password (empty to recover): )Zhidez!Confirm password recovery (y/n): z#The recovery code has been sent to zEnter recovery code: zEnter first name: z!Enter last name (empty to skip): 
))r;   Zsign_in_botprintr   r   r>   r#   rM   Z	send_coder   ZMESSAGEr   ZSentCodeTypeZAPPrw   CALLZ
FLASH_CALLZFRAGMENT_SMSZ
EMAIL_CODEtyper?   Zsign_inZphone_code_hashr   formatZget_password_hintr@   rH   Zsend_recovery_codeZrecover_password	Exceptionlog	exceptionZcheck_password
isinstancer!   Zsign_upr"   textZaccept_terms_of_serviceid)r^   valueconfirmZ	sent_codeeZsent_code_descriptionsZ	signed_inZemail_patternZrecovery_codeZ
first_name	last_nameZ	signed_upr`   r`   ra   	authorizeK  s    
 




0zClient.authorize)rD   c             C   s
   || _ dS )a  Set the parse mode to be used globally by the client.

        When setting the parse mode with this method, all other methods having a *parse_mode* parameter will follow the
        global value by default.

        Parameters:
            parse_mode (:obj:`~pyrogram.enums.ParseMode`):
                By default, texts are parsed using both Markdown and HTML styles.
                You can combine both syntaxes together.

        Example:
            .. code-block:: python

                from pyrogram import enums

                # Default combined mode: Markdown + HTML
                await app.send_message("me", "1. **markdown** and <i>html</i>")

                # Force Markdown-only, HTML is disabled
                app.set_parse_mode(enums.ParseMode.MARKDOWN)
                await app.send_message("me", "2. **markdown** and <i>html</i>")

                # Force HTML-only, Markdown is disabled
                app.set_parse_mode(enums.ParseMode.HTML)
                await app.send_message("me", "3. **markdown** and <i>html</i>")

                # Disable the parser completely
                app.set_parse_mode(enums.ParseMode.DISABLED)
                await app.send_message("me", "4. **markdown** and <i>html</i>")

                # Bring back the default combined mode
                app.set_parse_mode(enums.ParseMode.DEFAULT)
                await app.send_message("me", "5. **markdown** and <i>html</i>")
        N)rD   )r^   rD   r`   r`   ra   set_parse_mode  s    $zClient.set_parse_mode)peersrs   c       
         sr  d}g }xP|D ]F}t |ddr(d}qd }d }t|tjjr|j}|j}|jrZ|j n|j	rp|j	d j nd }|j
}|jrdnd}	nt|tjjtjjfr|j }d}d}	nt|tjjrt|j}|j}|jr|j n|j	r|j	d j nd }|jr
dnd	}	n4t|tjjrt|j}|j}|jr<dnd	}	nq||||	||f qW | j|I d H  |S )
NFminTr   botusergroupchannelZ
supergroup)getattrr   r   typesr!   r   access_hashusernamerM   Z	usernamesZphoner   ChatZChatForbiddenChannelr   get_channel_id	broadcastZChannelForbiddenappendrO   Zupdate_peers)
r^   r   is_minZparsed_peerspeerr   r>   peer_idr   Z	peer_typer`   r`   ra   fetch_peers  sF    zClient.fetch_peersc          
      s  t  | _t|tjjtjjfrt| 	|j
I d H | 	|jI d H f}dd |j
D }dd |jD }xR|jD ]N}ttt|dd dd dd pt|dd }t|dd }t|dd }t|tjjrt| t|tjjr|r|j}	t|	tjjsy\| tjjj| t|I d H tjjtjj|jj|jjd	gd
|| |dI d H }
W n tk
rp   Y n@X t|
tjjjs|dd |
j
D  |dd |
jD  | j j!"|||f qtW nt|tjj#tjj$fr~| tjjj%|j&|j' |j(ddI d H }
|
j)rZ| j j!"tjj*|
j)d |j&|j'ddd |
j
D dd |
jD f n"|
j+r| j j!"|
j+d i i f nBt|tjj,r| j j!"|ji i f nt|tjj-rt| d S )Nc             S   s   i | ]}||j qS r`   )r   ).0ur`   r`   ra   
<dictcomp>   s    z)Client.handle_updates.<locals>.<dictcomp>c             S   s   i | ]}||j qS r`   )r   )r   cr`   r`   ra   r   !  s    messager   
channel_idpts	pts_count)Zmin_idZmax_id)ranges)r   filterr   limitc             S   s   i | ]}||j qS r`   )r   )r   r   r`   r`   ra   r   H  s    c             S   s   i | ]}||j qS r`   )r   )r   r   r`   r`   ra   r   I  s    )r   dateZqtsr   )r   r   r   c             S   s   i | ]}||j qS r`   )r   )r   r   r`   r`   ra   r   \  s    c             S   s   i | ]}||j qS r`   )r   )r   r   r`   r`   ra   r   ]  s    ).r   r[   r\   r   r   r   ZUpdatesZUpdatesCombinedanyr   userschatsrq   r   ZUpdateChannelTooLongr~   infoZUpdateNewChannelMessager   ZMessageEmptyro   rp   ZGetChannelDifferenceZresolve_peerr   r   ZChannelMessagesFilterZMessageRanger   r   ZChannelDifferenceEmptyupdaterP   Zupdates_queue
put_nowaitZUpdateShortMessageZUpdateShortChatMessageZGetDifferencer   r   r   Znew_messagesZUpdateNewMessageZother_updatesZUpdateShortZUpdatesTooLong)r^   rq   r   r   r   r   r   r   r   r   Zdiffr`   r`   ra   handle_updates  st    


zClient.handle_updatesc          
      s  | j  I d H  t| j  I d H d k| j  I d H d k| j  I d H d k| j  I d H d kg}|r(| jrr| jszt	d| j | jI d H  | j 
dI d H  | j dI d H  | j | jI d H  | j t| | j 
 I d H | j  I d H  I d H I d H  | j d I d H  | j d I d H  n| j  I d H s| jrX| j | jI d H  nxydttdI d H }|dkrtd wZtd| dI d H  }|dkr| j |I d H  P W n, tk
r } zt| W d d }~X Y nX qZW d S )	Nz_The API key is required for new authorizations. More info: https://docs.pyrogram.org/start/auth   r   z&Enter the api_id part of the API key: zInvalid valuezIs "z" correct? (y/N): ru   )rO   openr   r:   auth_keyuser_idZis_botr2   r3   AttributeErrordc_idr   r   createrL   r#   ry   rM   r}   )r^   Zsession_emptyr   r   r   r`   r`   ra   load_sessiong  sD    $

zClient.load_sessionc             C   s>  | j rD| j  }x6dD ](}||g rdd | j | D ||< qW nd S |ddr:|d }|dg }|dg }d	}|sZxtt|d
ddD ]}d
|jj	|j
f }t|}	xt|	 D ]}
yfx`t|	|
jD ]P\}}t|trt|tr| || td| jt|j|
|| |d7 }qW W q tk
rL   Y qX qW qW nLxH|D ]>\}}|d
 | }d}yt|}	W n* tk
r   td| j| wbY nX dt|	krtd| j| qb|d krt|	 }d}x|D ]}
ylxft|	|
jD ]V\}}t|tr
t|tr
| || td| jt|j|
|| |d7 }q
W W n2 tk
r   |rtd| j|
| Y nX qW qbW |rxH|D ]>\}}|d
 | }d}yt|}	W n* tk
r   td| j| wY nX dt|	kr(td| j| q|d krBt|	 }d}x|D ]}
ylxft|	|
jD ]V\}}t|tr\t|tr\| || td| jt|j|
|| |d8 }q\W W n2 tk
r   |rtd| j|
| Y nX qHW qW |d	kr*td| j||dkrdnd| ntd| j| d S )N)includeexcludec             S   s,   g | ]$}|  d  |  dd p$dfqS )r   r$   N)split)r   ir`   r`   ra   
<listcomp>  s   z'Client.load_plugins.<locals>.<listcomp>ZenabledTrootr   r   r   ./z*.pyz*[{}] [LOAD] {}("{}") in group {} from "{}"r$   z-[%s] [LOAD] Ignoring non-existent module "%s"__path__z#[%s] [LOAD] Ignoring namespace "%s"Fz9[{}] [LOAD] Ignoring non-existent function "{}" from "{}"z/[%s] [UNLOAD] Ignoring non-existent module "%s"z%[%s] [UNLOAD] Ignoring namespace "%s"z,[{}] [UNLOAD] {}("{}") from group {} in "{}"z;[{}] [UNLOAD] Ignoring non-existent function "{}" from "{}"z.[{}] Successfully loaded {} plugin{} from "{}"s z[%s] No plugin loaded from "%s")rC   copygetsortedr
   replacerglobjoinparentpartsstemr   varskeysr   handlersr   r   rL   add_handlerr~   r   r|   r1   r{   __name__r}   ImportErrorwarningdirZremove_handler)r^   rC   optionr   r   r   countpathmodule_pathmoduler1   handlerr   r   Zwarn_non_existent_functionsr`   r`   ra   load_plugins  s    

 


 


 
 zClient.load_pluginsc          
      s0  |\}}}}}}}|s$t j|ddnd  t jtddt j||d }	|rVt nt|	d}
yJxD| 	||dd||2 y3 d H }W n
 t
k
sX |
| qx   Y  W W nH tk
r } z*|s|
  t |	 t|tjr|d S d }~X Y n:X |r||
_|
S |
  t j|	d }t|	| |S d S )NT)exist_okz\\r   z.tempwbr   )osmakedirsr   abspathresubr   r   r   get_fileStopAsyncIterationwriteBaseExceptioncloseremover   rS   ZCancelledErrorr1   splitextshutilmove)r^   packetfile_id	directory	file_namer=   	file_sizeprogressprogress_argsZtemp_file_pathfilechunkr   	file_pathr`   r`   ra   handle_download  s*    $.
zClient.handle_downloadr`   )r   r   r   offsetr   r   rs   c             C  s  | j 4 I d H v |j}|tjkr|jdkrBtjj|j|jd}n8|jdkr`tjj	|j d}ntjj
t|j|jd}tjj||j|jtjkd}	nD|tjkrtjj|j|j|j|jd}	ntjj|j|j|j|jd}	d}
t|pd}d}t|| }|j}t| ||| j I d H kr@t| || j I d H  I d H n| j I d H | j I d H d	d
}z
y|  I d H  || j I d H kr| !tj"j#j$|dI d H }|!tj"j#j%|j&|j'dI d H  |j!tj"j(j)|	||dddI d H }t*|tjj(j+rx|j'}|V  |
d7 }
||7 }|rt,j-||dkrBt.||n||f| }t/0|rj| I d H  n| j12| j3|I d H  t4||k s|
|krP |j!tj"j(j)|	||dddI d H }qW n\t*|tjj(j5r$t| |jt| |j| j I d H  I d H | j I d H d	d	d}zy|  I d H  x|!tj"j(j6|j7||dI d H }t*|tjj(j8ry&|!tj"j(j9|j7|j:dI d H  W n t;k
r   P Y nX q6|j'}t<=||j>t?|j@d d |d Add }|!tj"j(jB|j7|dI d H }xLtC|D ]@\}}||jD| |jD|d   }tEF|jGtH|I kd qW |V  |
d7 }
||7 }|rt,j-||dkrt.||n||f| }t/0|r| I d H  n| j12| j3|I d H  t4||k s|
|kr6P q6W W n( tJk
r } z|W d d }~X Y nX W d |K I d H  X W nF tLjMk
r@    Y n. tJk
rl } ztNO| W d d }~X Y nX W d |K I d H  X W d Q I d H R X d S )Nr   )r   r   )chat_id)r   r   )r   Zphoto_idbig)r   r   file_referenceZ
thumb_sizeii   T)is_media)r   )r   bytes)locationr   r      )rG   r$   )r   Zis_cdn)
file_tokenr   r   )r   request_token   r0   r   )r   r   z$h.hash == sha256(cdn_chunk).digest())PrV   	file_typer'   Z
CHAT_PHOTOr   r   r   ZInputPeerUserZchat_access_hashZInputPeerChatZInputPeerChannelr   r   ZInputPeerPhotoFileLocationZmedia_idZthumbnail_sourcer(   ZCHAT_PHOTO_BIGZPHOTOZInputPhotoFileLocationr   r   Zthumbnail_sizeZInputDocumentFileLocationabsr   r   rO   r   r:   r   r   rb   ro   rp   authZExportAuthorizationZImportAuthorizationr   r   uploadZGetFiler   File	functoolspartialr   inspectiscoroutinefunctionr]   Zrun_in_executorrN   lenZFileCdnRedirectZ
GetCdnFiler   ZCdnFileReuploadNeededZReuploadCdnFiler   r   r   Zctr256_decryptZencryption_key	bytearrayZencryption_ivto_bytesZGetCdnFileHashes	enumerater   r   checkhashr   digestr}   rd   pyrogramZStopTransmissionr~   r   )r^   r   r   r   r   r   r   r  r   r   currenttotal
chunk_sizeZoffset_bytesr   rR   Zexported_authrr   funcZcdn_sessionZr2Zdecrypted_chunkhashesr   hZ	cdn_chunkr   r`   r`   ra   r   )  s   	






8( zClient.get_file)filenamers   c             C   s   | j |d S )Nr   )	mimetypes
guess_type)r^   r  r`   r`   ra   guess_mime_type  s    zClient.guess_mime_type)	mime_typers   c             C   s   | j |S )N)r  guess_extension)r^   r  r`   r`   ra   r    s    zClient.guess_extension)r   r   r   Nr`   )Ir   
__module____qualname____doc__r   ZAPP_VERSIONplatformpython_implementationpython_versionZDEVICE_MODELsystemreleaseZSYSTEM_VERSIONZ	LANG_CODEr
   sysargvr   Z
PARENT_DIRr   compileZINVITE_LINK_REr   r   	cpu_countZWORKERSZWORKDIRrm   ZMAX_CONCURRENT_TRANSMISSIONSr	   r  readfpr   r)   r   Z	ParseModeDEFAULTr   ZSLEEP_THRESHOLDstrr   rL   booldictrK   rc   rg   rh   ri   rr   r!   r   r   r   r   r   r   r   r   r   r   r   r   r   r&   r   tupler   r   r   r  r  __classcell__r`   r`   )r_   ra   r,   @   st   t

NIv&*0P3r      Qr,   c               @   s*   e Zd ZedddZdd Zdd ZdS )	rX   )capacityc             C   s   || _ i | _d S )N)r3  store)r^   r3  r`   r`   ra   rK   	  s    zCache.__init__c             C   s   | j |d S )N)r4  r   )r^   keyr`   r`   ra   __getitem__  s    zCache.__getitem__c             C   s^   || j kr| j |= || j |< t| j | jkrZx,t| jd d D ]}| j tt| j = q@W d S )Nr   r$   )r4  r  r3  rangenextiter)r^   r5  r   _r`   r`   ra   __setitem__  s    

zCache.__setitem__N)r   r   r!  rL   rK   r6  r;  r`   r`   r`   ra   rX     s   rX   )KrS   r  r	  loggingr   r#  r   r   r(  Zconcurrent.futures.threadr   r   r   hashlibr   	importlibr   ior   r   r  r	   pathlibr
   typingr   r   r   r   r   r  r   r   r   r   r   Zpyrogram.cryptor   Zpyrogram.errorsr   r   r   r   r   Zpyrogram.handlers.handlerr   Zpyrogram.methodsr   Zpyrogram.sessionr   r   Zpyrogram.storager   r    Zpyrogram.typesr!   r"   Zpyrogram.utilsr#   rP   r%   r   r&   r'   r(   r)   rQ   r*   Zsession.internalsr+   	getLoggerr   r~   r,   rX   r`   r`   r`   ra   <module>   sZ   
       O