U
    gL                     @   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m	Z	m
Z
mZ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mZmZmZmZmZmZmZ G dd dZ dS )    N   )BreaklineStatusPrinterMultilineLoggerMultilinePrinterQuietMultilinePrinter)IDENTITY
NO_DEFAULTLockingUnsupportedError	NamespaceRetryManagerclasspropertydecodeArgumentdeprecation_warningencodeFilenameformat_bytesjoin_nonemptyparse_bytesremove_startsanitize_openshell_quotetimeconverttimetuple_from_msectry_callc                	   @   s  e Zd ZdZdZdZdd Zdd Zdd	 ZeZ	e
d
d Zedd Zedd Zedd Zedd ZeeefddZedd Zedd Zedd Ze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+d,d-Zed.d/d+d0d1 Zed2d3d4 Z ed5d6d7 Z!d8d9 Z"d:d; Z#d_d=d>Z$d?d@ Z%e&dAdAdBdCdDdEdEdFZ'dGdH Z(dIdJ Z)dKdL Z*dMdN Z+ed/fdOdPZ,dQdR Z-edSdT Z.d`dUdVZ/dWdX Z0dYdZ Z1d[d\ Z2dad]d^Z3dS )bFileDownloaderaN	  File Downloader class.

    File downloader objects are the ones responsible of downloading the
    actual video file and writing it to disk.

    File downloaders accept a lot of parameters. In order not to saturate
    the object constructor with arguments, it receives a dictionary of
    options instead.

    Available options:

    verbose:            Print additional info to stdout.
    quiet:              Do not print messages to stdout.
    ratelimit:          Download speed limit, in bytes/sec.
    throttledratelimit: Assume the download is being throttled below this speed (bytes/sec)
    retries:            Number of times to retry for expected network errors.
                        Default is 0 for API, but 10 for CLI
    file_access_retries:   Number of times to retry on file access error (default: 3)
    buffersize:         Size of download buffer in bytes.
    noresizebuffer:     Do not automatically resize the download buffer.
    continuedl:         Try to continue downloads if possible.
    noprogress:         Do not print the progress bar.
    nopart:             Do not use temporary .part files.
    updatetime:         Use the Last-modified header to set output file timestamps.
    test:               Download only first bytes to test the downloader.
    min_filesize:       Skip files smaller than this size
    max_filesize:       Skip files larger than this size
    xattr_set_filesize: Set ytdl.filesize user xattribute with expected size.
    progress_delta:     The minimum time between progress output, in seconds
    external_downloader_args:  A dictionary of downloader keys (in lower case)
                        and a list of additional command-line arguments for the
                        executable. Use 'default' as the name for arguments to be
                        passed to all downloaders. For compatibility with youtube-dl,
                        a single list of args can also be used
    hls_use_mpegts:     Use the mpegts container for HLS videos.
    http_chunk_size:    Size of a chunk for chunk-based HTTP downloading. May be
                        useful for bypassing bandwidth throttling imposed by
                        a webserver (experimental)
    progress_template:  See YoutubeDL.py
    retry_sleep_functions: See YoutubeDL.py

    Subclasses of this one must re-define the real_download method.
    i(  Nc                 C   sN   |  | g | _|| _|   | | j | jdrJt | _	t
 | _dS )z6Create a FileDownloader object with the given options.progress_deltaN)_set_ydl_progress_hooksparams_prepare_multiline_statusadd_progress_hookreport_progressget	threadingLock_progress_delta_locktime	monotonic_progress_delta_time)selfydlr    r*   </tmp/pip-unpacked-wheel-q5ljy6pj/yt_dlp/downloader/common.py__init__V   s    

zFileDownloader.__init__c                 C   s0   || _ dD ] }t| |s
t| |t|| q
d S )N)	r   Zdeprecated_featurereport_errorreport_file_already_downloadedZreport_warningto_console_titleZ	to_stderrZtroublewrite_debug)r)   hasattrsetattrgetattr)r(   r)   funcr*   r*   r+   r   a   s    
zFileDownloader._set_ydlc                 O   s"   | j j|d| jdi| d S )Nquiet)r)   	to_screenr   r!   )r(   argsZkargsr*   r*   r+   r6   r   s    zFileDownloader.to_screenc                 C   s   t dd| jd d  S )Nz(?<=[a-z])(?=[A-Z])_)resub__name__lower)clsr*   r*   r+   FD_NAMEw   s    zFileDownloader.FD_NAMEc                 C   s6   | d krdS t | d }|jdkr&dS d|d d  S )Nz Unknowni  c   z--:--:--z%02d:%02d:%02d)r   hours)secondsr%   r*   r*   r+   format_seconds{   s    
zFileDownloader.format_secondsc                 C   s   t | |ddS )Nz00:z>8s)r   rD   )r>   rC   r*   r*   r+   
format_eta   s    zFileDownloader.format_etac                 C   s    |d krd S t | t | d S )Ng      Y@float)byte_counterZdata_lenr*   r*   r+   calc_percent   s    zFileDownloader.calc_percentc                 C   s   | d krdS | ddS )Nz  N/A%z>5.1f%r*   )percentr*   r*   r+   format_percent   s    zFileDownloader.format_percentc           	      C   s   |t kr2|| }}d ||fkr"d S tt|| S || }}|d krHd S |d krXt }| |||}|ott|t| | S N)r   intrG   r%   
calc_speed)	r>   Zstart_or_rateZnow_or_remainingtotalcurrentrate	remainingstartnowr*   r*   r+   calc_eta   s    

zFileDownloader.calc_etac                 C   s(   ||  }|dks|dk rd S t || S )Nr   MbP?rF   )rT   rU   bytesZdifr*   r*   r+   rO      s    zFileDownloader.calc_speedc                 C   s   | d krdS t | ddS )Nz Unknown B/s>10sz/s)r   )speedr*   r*   r+   format_speed   s    zFileDownloader.format_speedc                 C   s   | t dkrdS t| S )Ninf)rG   rN   )retriesr*   r*   r+   format_retries   s    zFileDownloader.format_retriesc                 C   s   t j| rt j| S dS )Nr   )ospathisfilegetsize)Zunencoded_filenamer*   r*   r+   filesize_or_none   s    zFileDownloader.filesize_or_nonec                 C   sb   t |d d}tt |d dd}| dk r2t|S ||  }||krJt|S ||k rZt|S t|S )Ng       @g      ?i  @ rW   )maxminrN   )Zelapsed_timerX   Znew_minZnew_maxrR   r*   r*   r+   best_block_size   s    zFileDownloader.best_block_sizec                 C   s   t d t| S )z:Parse a string indicating a byte quantity into an integer.zvyt_dlp.FileDownloader.parse_bytes is deprecated and may be removed in the future. Use yt_dlp.utils.parse_bytes instead)r   r   )Zbytestrr*   r*   r+   r      s    zFileDownloader.parse_bytesc                 C   s~   | j d}|dks|dkr dS |dkr0t }|| }|dkrDdS t|| }||krzt|| | }|dkrzt| dS )z3Sleep if the download speed is over the rate limit.Z	ratelimitNr   g        )r   r!   r%   rG   sleep)r(   
start_timerU   rH   Z
rate_limitelapsedrZ   Z
sleep_timer*   r*   r+   	slow_down   s    zFileDownloader.slow_downc                 C   sB   | j dds6|dks6tjt|r:tjt|s:|S |d S )z4Returns a temporary filename for the given filename.nopartF-.part)r   r!   r_   r`   existsr   ra   r(   filenamer*   r*   r+   	temp_name   s    zFileDownloader.temp_namec                 C   s    | dr|d td  S |S )Nrm   )endswithlenro   r*   r*   r+   undo_temp_name   s    
zFileDownloader.undo_temp_namec                 C   s   |d S )Nz.ytdlr*   ro   r*   r*   r+   ytdl_filename   s    zFileDownloader.ytdl_filenameF)fatalc                   s(    fddfdd}t t j|S )Nc                   sF   t j| || j fddr"d n fdd jdi ddS )Nc                    s    t dd  d|  fS )Ng{Gz?z[download] Unable to  file: )r%   rg   r6   eactionfdr*   r+   <lambda>       zIFileDownloader.wrap_file_access.<locals>.error_callback.<locals>.<lambda>c                    s    d  d|  S )Nz
Unable to rw   r-   rx   rz   r*   r+   r}      r~   retry_sleep_functionsZfile_access)infowarnerror
sleep_func)r   report_retry_FileDownloader__to_screenr   r!   )errcountr]   r|   )r{   rv   r|   r+   error_callback   s       z7FileDownloader.wrap_file_access.<locals>.error_callbackc                    s   t | jdd | dD ]l}z|| f||W   S  tk
r } z2|jtjtjfkrd||_W Y q||dd W 5 d }~X Y qX qd S )NZfile_access_retries   r      r   )	r   r   r!   OSErrorerrnoEACCESEINVALr   r   )r(   r4   r7   kwargsretryr   )r   r*   r+   wrapper   s    z0FileDownloader.wrap_file_access.<locals>.wrapper)	functoolspartialpartialmethod)r{   rv   r   r*   )r{   r   rv   r+   wrap_file_access   s    
zFileDownloader.wrap_file_accessopenTc                 C   s8   t ||\}}t|dd s0| jtj ddd ||fS )Nlockedz. Proceeding without lockingT)Z	only_once)r   r3   r0   r	   msg)r(   rp   Z	open_modefr*   r*   r+   r      s    zFileDownloader.sanitize_openremovec                 C   s   t j|rt | d S rM   )r_   r`   ra   r   ro   r*   r*   r+   
try_remove  s    zFileDownloader.try_removerenamec                 C   s   ||krd S t || d S rM   )r_   replace)r(   Zold_filenameZnew_filenamer*   r*   r+   
try_rename
  s    zFileDownloader.try_renamec              	   C   s~   |dkrdS t jt|s dS |}|dkr0dS t|}|dkrD|S |dkrPdS tt t |t		 |f W 5 Q R X |S )z4Try to set the last-modified time of the given file.Nr   )
r_   r`   ra   r   r   
contextlibsuppress	Exceptionutimer%   )r(   rp   Zlast_modified_hdrZtimestrZfiletimer*   r*   r+   	try_utime  s    zFileDownloader.try_utimec                 C   s   |  d|  dS )zReport destination filename.z[download] Destination: Nr6   ro   r*   r*   r+   report_destination#  s    z!FileDownloader.report_destinationr   c                 C   s   | j drt | _nb| jj dr:t| jj d || _n>| j drZt| jjj|| _nt	| jjj|| j d | _| jj
jo| jj
jdk| j_| jj
j| j_d S )N
noprogressloggerZprogress_with_newliner5   no_color)r   r!   r   
_multiliner)   r   r   Z
_out_filesoutr   Z_allow_colorsallow_colorsZ_HAVE_FULLCAP)r(   linesr*   r*   r+   r   '  s    
z(FileDownloader._prepare_multiline_statusc                 C   s   | j   d S rM   )r   endr(   r*   r*   r+   _finish_multiline_status3  s    z'FileDownloader._finish_multiline_statusz
light blueZyellowZgreenz
bold white )downloaded_bytesrK   etarZ   ri   total_bytestotal_bytes_estimatec                 C   s   | j jD ]2\}}d| d}||kr&q| || |||< q|| |d< | }|d |d |d}| jdi }| j| j	
|dpd||d	pd
 | | j	
|dpd| d S )Nr8   _strZ_default_template	info_dict)r   progressprogress_templatedownloadz)[download] %(progress._default_template)sZprogress_idxr   zdownload-titlez%yt-dlp %(progress._default_template)s)ProgressStylesZitems__format_progresscopypopr   r!   r   Zprint_at_liner)   Zevaluate_outtmplr/   )r(   sZdefault_templatenamestyleZprogress_dictr   r*   r*   r+   _report_progress_status@  s(    

z&FileDownloader._report_progress_statusc                 O   s   | j j| jj| jjf||S rM   )r)   _format_textr   streamr   )r(   r7   r   r*   r*   r+   r   T  s     zFileDownloader._format_progressc                    s  dd fdd
} fdd} d dkr| j d	r@| d
 t fdd} || | |d|  d| dd | 	 t
d|d|d|ddd  d dkrd S | j d }r
| j0 t | jk rW 5 Q R  d S |  j|7  _W 5 Q R X  |  d |  d| t fdd fdd fdd|d|d|d|  dd |d d!d"d#d$d}||d%d&7 }| 	 | d S )'Nr   )defaultc                    s2   |D ](^ }}t  fdd|D r|  S q| S )Nc                 3   s   | ]}  |d k	V  qd S rM   )r!   ).0r   r   r*   r+   	<genexpr>[  s     zFFileDownloader.report_progress.<locals>.with_fields.<locals>.<genexpr>)all)r   Ztupsfieldstmplr   r*   r+   with_fieldsY  s    
z3FileDownloader.report_progress.<locals>.with_fieldsc                    s   t  | dS )NrY   )r   r!   )kr   r*   r+   r}   _  r~   z0FileDownloader.report_progress.<locals>.<lambda>statusfinishedr   z[download] Download completedc                      s    d  d  S )Nr   ri   r*   r*   r   r*   r+   r}   d  r~   r   ri   d   )rZ   
_speed_str_total_bytes_str_elapsed_str_percent_strz100%%)r   zof %(_total_bytes_str)s)ri   zin %(_elapsed_str)s)rZ   zat %(_speed_str)s )delimZdownloadingr   r   rZ   c                      s   d d   d  S )Nr   r   r   r*   r*   r   r*   r+   r}     r~   c                      s   d d   d  S )Nr   r   r   r*   r*   r   r*   r+   r}     r~   c                      s    d dkodS )Nr   r   r*   r*   r   r*   r+   r}     r~   r   r   )Z_eta_strr   r   r   Z_total_bytes_estimate_strZ_downloaded_bytes_strr   )r   zK%(_percent_str)s of %(_total_bytes_str)s at %(_speed_str)s ETA %(_eta_str)s)r   zU%(_percent_str)s of ~%(_total_bytes_estimate_str)s at %(_speed_str)s ETA %(_eta_str)s)r   ri   z>%(_downloaded_bytes_str)s at %(_speed_str)s (%(_elapsed_str)s))r   z+%(_downloaded_bytes_str)s at %(_speed_str)sz3%(_percent_str)s at %(_speed_str)s ETA %(_eta_str)s)fragment_indexZfragment_countz- (frag %(fragment_index)s/%(fragment_count)s))r   z (frag %(fragment_index)s))r   r!   r6   r   updater[   striprD   rL   r   r   r$   r%   r&   r'   rE   )r(   r   r   Z_format_bytesrZ   Zupdate_deltaZmsg_templater*   r   r+   r    X  sh    



zFileDownloader.report_progressc                 C   s   |  d|  dS )z'Report attempt to resume at given byte.z%[download] Resuming download at byte Nr   )r(   Z
resume_lenr*   r*   r+   report_resuming_byte  s    z#FileDownloader.report_resuming_bytec                    s|   |t krdnd}tj||| j fdd|s0tn
 fdd jdi |pNd|rpd|dkrbd	nd
|  ndd dS )zReport retryFfragmentc                    s     d|  S )Nz[download] Got error: )r   )r   r   r*   r+   r}     r~   z-FileDownloader.report_retry.<locals>.<lambda>c                    s     d|  S )Nz[download] Got error: r   rx   r   r*   r+   r}     r~   r   httpNr   r   )r   r   r   r   suffix)r   r   r   r   r   r   r!   )r(   r   r   r]   Z
frag_indexrv   Zis_fragr*   r   r+   r     s       
"zFileDownloader.report_retryc                 C   s   |  d dS )z,Report it was impossible to resume download.z[download] Unable to resumeNr   r   r*   r*   r+   report_unable_to_resume  s    z&FileDownloader.report_unable_to_resumec                 C   s   dS )zp Whether the downloader can download the fragments from the manifest.
        Redefine in subclasses if needed. Nr*   )manifestr*   r*   r+   supports_manifest  s    z FileDownloader.supports_manifestc           	      C   s   | j dd otjt|}t|ds| j ddoVtjt|oV| j dd }|dkr|sh|r| | | 	|dtj
t|d	| |   d
S |r| j dpd}n(| j dpd}t|| j dp|}|dkr| d|dd t| | ||}|   |dfS )zpDownload to a filename using the info from info_dict
        Return True on success and False otherwise
        Z
overwritesTwriteZ
continuedlrk   Frl   r   )rp   r   r   )TFZsleep_interval_subtitlesr   sleep_intervalZmax_sleep_intervalz[download] Sleeping z.2fz seconds ...)r   r!   r_   r`   rn   r   r1   ra   r.   _hook_progressrb   r   randomuniformr6   r%   rg   real_download)	r(   rp   r   ZsubtitleZnooverwrites_and_existsZcontinuedl_and_existsr   Zmin_sleep_intervalretr*   r*   r+   r     sB    

 

zFileDownloader.downloadc                 C   s   t ddS )z.Real download process. Redefine in subclasses.z-This method must be implemented by subclassesN)NotImplementedError)r(   rp   r   r*   r*   r+   r     s    zFileDownloader.real_downloadc                 C   s    ||d< | j D ]}|| qd S )Nr   )r   )r(   r   r   phr*   r*   r+   r     s    
zFileDownloader._hook_progressc                 C   s   | j | d S rM   )r   append)r(   r   r*   r*   r+   r     s    z FileDownloader.add_progress_hookc                 C   sT   | j ddsd S dd |D }|d kr8tj|d }| | dt|  d S )NverboseFc                 S   s   g | ]}t |qS r*   )r   )r   ar*   r*   r+   
<listcomp>  s     z-FileDownloader._debug_cmd.<locals>.<listcomp>r   z command line: )r   r!   r_   r`   basenamer0   r   )r(   r7   ZexeZstr_argsr*   r*   r+   
_debug_cmd  s    zFileDownloader._debug_cmd)r   )F)N)4r<   
__module____qualname____doc__Z_TEST_FILE_SIZEr   r,   r   r6   r   r   r?   staticmethodrD   classmethodrE   rI   rL   r   rV   rO   r[   r^   rc   rf   r   rj   rq   rt   ru   r   r   r   r   r   r   r   r   r
   r   r   r   r    r   r   r   r   r   r   r   r   r   r*   r*   r*   r+   r   &   s   ,
















=


)	r   )!r   r   r   r_   r   r:   r"   r%   Z
minicursesr   r   r   r   utilsr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r*   r*   r*   r+   <module>   s   P