U
    7sg$                     @   s   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mZ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 dd Zdd ZG dd dZdS )    N)Var)DictUnion)
work_loads)Clientutilsraw   )get_file_ids)SessionAuth)AuthBytesInvalid)FIleNotFound)FileIdFileTypeThumbnailSourcec              	      s(   dt ttt| d dd d S )N   i   
   )maxminmathceillog2)length r   :/opt/bot/vods_filmes/script/WebStreamer/utils/custom_dl.py
chunk_size   s    r   c                    s   | | | 8 } | S )Nr   )offset	chunksizer   r   r   
offset_fix   s    r   c                
   @   s   e Zd ZedddZeedddZeedddZeee	d	d
dZ
eeeejjejjejjf dddZeeeeeeeeedf dddZddddZdS )ByteStreamer)clientc                 C   s$   d| _ || _i | _t|   dS )a'  A custom class that holds the cache of a specific client and class functions.
        attributes:
            client: the client that the cache is for.
            cached_file_ids: a dict of cached file IDs.
            cached_file_properties: a dict of cached file properties.
        
        functions:
            generate_file_properties: returns the properties for a media of a specific message contained in Tuple.
            generate_media_session: returns the media session for the DC that contains the media file.
            yield_file: yield a file from telegram servers for streaming.
            
        This is a modified version of the <https://github.com/eyaadh/megadlbot_oss/blob/master/mega/telegram/utils/custom_download.py>
        Thanks to Eyaadh <https://github.com/eyaadh>
        i  N)clean_timerr!   cached_file_idsasynciocreate_taskclean_cache)selfr!   r   r   r   __init__   s    zByteStreamer.__init__)
message_idreturnc                    s4   || j kr*| |I dH  td|  | j | S )z
        Returns the properties of a media of a specific message in a FIleId class.
        if the properties are cached, then it'll return the cached results.
        or it'll generate the properties from the Message ID and cache them.
        Nz+Cached file properties for message with ID )r#   generate_file_propertiesloggingdebug)r'   r)   r   r   r   get_file_properties/   s    
z ByteStreamer.get_file_propertiesc                    sd   t | jtj|I dH }td|  |s@td| d t|| j|< td|  | j| S )z
        Generates the properties of a media file on a specific message.
        returns ths properties in a FIleId class.
        Nz4Generated file ID and Unique ID for message with ID zMessage with ID z
 not foundzCached media message with ID )r
   r!   r   BIN_CHANNELr,   r-   r   r#   )r'   r)   file_idr   r   r   r+   :   s    
z%ByteStreamer.generate_file_properties)r!   r0   r*   c              	      s  |j |jd}|dkrv|j|j I dH krt||jt||j|j I dH  I dH |j I dH dd}| I dH  t	dD ]~}|
tjjj|jdI dH }z.|
tjjj|j|jdI dH  W  qVW q tk
r   td|j  Y qY qX q| I dH  tn:t||j|j I dH |j I dH dd}| I dH  td|j  ||j |j< ntd	|j  |S )
z
        Generates the media session for the DC that contains the media file.
        This is required for getting the bytes from Telegram servers.
        NT)is_media   )dc_id)idbytesz#Invalid authorization bytes for DC zCreated media session for DC z"Using cached media session for DC )media_sessionsgetr3   storager   r   	test_modecreatestartrangeinvoker   	functionsauthExportAuthorizationImportAuthorizationr4   r5   r   r,   r-   stopauth_key)r'   r!   r0   media_session_exported_authr   r   r   generate_media_sessionH   s\    
  	
 

z#ByteStreamer.generate_media_session)r0   r*   c                    s   | j }|tjkr| jdkr0tjj| j| jd}n8| jdkrNtjj| j d}ntjj	t
| j| jd}tj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}|S )z?
        Returns the file location for the media file.
        r   )user_idaccess_hash)chat_id)
channel_idrI   )peer	volume_idlocal_idbig)r4   rI   file_reference
thumb_size)	file_typer   
CHAT_PHOTOrJ   r   typesInputPeerUserchat_access_hashInputPeerChatInputPeerChannelr   get_channel_idInputPeerPhotoFileLocationrM   rN   thumbnail_sourcer   CHAT_PHOTO_BIGPHOTOInputPhotoFileLocationmedia_idrI   rP   thumbnail_sizeInputDocumentFileLocation)r0   rR   rL   locationr   r   r   get_location   sB    

 



zByteStreamer.get_locationN)r0   indexr   first_part_cutlast_part_cut
part_countr   r*   c              
   C  s^  | j }t|  d7  < td| d | ||I dH }	d}
| |I dH }zz|	tjj	j
|||dI dH }t|tjj	jr|
|kr|j}|sq||7 }|dkr||| V  q|
dkr||d V  d|
  k r|krn n|V  |	tjj	j
|||dI dH }|
d7 }
qW n ttfk
r8   Y nX W 5 td t|  d8  < X dS )z
        Custom generator that yields the bytes of the media file.
        Modded from <https://github.com/eyaadh/megadlbot_oss/blob/master/mega/telegram/utils/custom_download.py#L20>
        Thanks to Eyaadh <https://github.com/eyaadh>
        r	   z&Starting to yielding file with client .Nz1Finished yielding file with {current_part} parts.)rb   r   limit)r!   r   r,   r-   rG   rc   r=   r   r>   uploadGetFile
isinstancerT   Filer5   TimeoutErrorAttributeError)r'   r0   rd   r   re   rf   rg   r   r!   rD   Zcurrent_partrb   rchunkr   r   r   
yield_file   sN      

  


zByteStreamer.yield_file)r*   c                    s,   t | jI dH  | j  td q dS )zD
        function to clean the cache to reduce memory usage
        NzCleaned the cache)r$   sleepr"   r#   clearr,   r-   )r'   r   r   r   r&      s    
zByteStreamer.clean_cache)__name__
__module____qualname__r   r(   intr   r.   r+   r   rG   staticmethodr   r   rT   r^   ra   rZ   rc   strrr   r&   r   r   r   r   r       s&   9
.
:r    )r   r$   r,   WebStreamerr   typingr   r   ZWebStreamer.botr   pyrogramr   r   r   file_propertiesr
   Zpyrogram.sessionr   r   pyrogram.errorsr   WebStreamer.server.exceptionsr   pyrogram.file_idr   r   r   r   r   r    r   r   r   r   <module>   s   