
    yfL                         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      Z y)    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            	          e Zd ZdZdZdZd Zd Zd ZeZ	e
d        Zed        Zed	        Zed
        Zed        Zeeefd       Zed        Zed        Zed        Zed        Zed        Zed        Zd Zd Zd Zd ZdddZ edd      d        Z ed      d        Z  ed      d         Z!d! Z"d" Z#d7d#Z$d$ Z% e&d%d%d&d'd(d)d)*      Z'd+ Z(d, Z)d- Z*d. Z+edfd/Z,d0 Z-ed1        Z.d8d2Z/d3 Z0d4 Z1d5 Z2d9d6Z3y):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                 4   | j                  |       g | _        || _        | j                          | j	                  | j
                         | j                  j                  d      r3t        j                         | _	        t        j                         | _        yy)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    s      :/usr/lib/python3/dist-packages/yt_dlp/downloader/common.py__init__zFileDownloader.__init__V   sq    c!&&(t334;;??+,(1(8D%(,(8D% -    c           	      h    || _         dD ]&  }t        | |      rt        | |t        ||             ( y )N)	r   deprecated_featurereport_errorreport_file_already_downloadedreport_warningto_console_title	to_stderrtroublewrite_debug)r,   hasattrsetattrgetattr)r+   r,   funcs      r-   r   zFileDownloader._set_ydla   s9    

 	8D 4&dGC$67	8r/   c                 r     | j                   j                  |d| j                  j                  d      i| y )Nquiet)r,   	to_screenr    r$   )r+   argskargss      r-   r?   zFileDownloader.to_screenr   s-    DJ(@JEJr/   c                 f    t        j                  dd| j                  d d       j                         S )Nz(?<=[a-z])(?=[A-Z])_)resub__name__lower)clss    r-   FD_NAMEzFileDownloader.FD_NAMEw   s*    vv,c3<<3DEKKMMr/   c                 T    | yt        | dz        }|j                  dkD  ryd|d d z  S )Nz Unknowni  c   z--:--:--z%02d:%02d:%02d)r   hours)secondsr(   s     r-   format_secondszFileDownloader.format_seconds{   s7    ?"7T>2::?$s)++r/   c                 <    t        | j                  |      d      dS )Nz00:z>8s)r   rP   )rI   rO   s     r-   
format_etazFileDownloader.format_eta   s    s11':EB3GHr/   c                 <    |y t        |       t        |      z  dz  S )Ng      Y@float)byte_counterdata_lens     r-   calc_percentzFileDownloader.calc_percent   s$    \"U8_4u<<r/   c                     | dS | ddS )Nz  N/A%z>5.1f% )percents    r-   format_percentzFileDownloader.format_percent   s    "?xC75/0CCr/   c                    |t         u r"||}}d ||fv ry t        t        |      |z        S ||}}|y |t        j                         }| j	                  |||      }|xr# t        t        |      t        |      z
  |z        S N)r	   intrU   r(   
calc_speed)	rI   start_or_ratenow_or_remainingtotalcurrentrate	remainingstartnows	            r-   calc_etazFileDownloader.calc_eta   s    J+-=)Di((uY'$.//"$4s=;))+C~~eS'2CU5\E'N:dBCCr/   c                 >    || z
  }|dk(  s|dk  ry t        |      |z  S )Nr   MbP?rT   )rh   ri   bytesdifs       r-   ra   zFileDownloader.calc_speed   s*    EkA:uU|c!!r/   c                 (    | dS t        |       ddS )Nz Unknown B/s>10sz/s)r   )speeds    r-   format_speedzFileDownloader.format_speed   s!    !&~S|E7J46PPR4SSr/   c                 8    | t        d      k(  rdS t        |       S )Ninf)rU   r`   )retriess    r-   format_retrieszFileDownloader.format_retries   s    5</uAS\Ar/   c                     t         j                  j                  |       rt         j                  j                  |       S y)Nr   )ospathisfilegetsize)unencoded_filenames    r-   filesize_or_nonezFileDownloader.filesize_or_none   s*    77>>,-77??#566r/   c                     t        |dz  d      }t        t        |dz  d      d      }| dk  rt        |      S || z  }||kD  rt        |      S ||k  rt        |      S t        |      S )Ng       @g      ?i  @ rl   )maxminr`   )elapsed_timerm   new_minnew_maxrf   s        r-   best_block_sizezFileDownloader.best_block_size   sq    eck3'c%#+s+W5%w<|#'>w<'>w<4yr/   c                 .    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   )bytestrs    r-   r   zFileDownloader.parse_bytes   s     	 a 	b7##r/   c                    | j                   j                  d      }||dk(  ry|t        j                         }||z
  }|dk  ryt        |      |z  }||kD  r-t        |      |z  |z
  }|dkD  rt        j                  |       yyy)z3Sleep if the download speed is over the rate limit.	ratelimitNr   g        )r    r$   r(   rU   sleep)r+   
start_timeri   rV   
rate_limitelapsedrq   
sleep_times           r-   	slow_downzFileDownloader.slow_down   s    [[__[1
!2;))+C
"c>l#g-:|,z9GCJA~

:&  r/   c                     | j                   j                  dd      sU|dk(  sPt        j                  j	                  t        |            r*t        j                  j                  t        |            s|S |dz   S )z4Returns a temporary filename for the given filename.nopartF-.part)r    r$   rx   ry   existsr   rz   r+   filenames     r-   	temp_namezFileDownloader.temp_name   sU    ;;??8U+x3x 89"''..Q_`hQiBjO'!!r/   c                 F    |j                  d      r|d t        d        S |S )Nr   )endswithlenr   s     r-   undo_temp_namezFileDownloader.undo_temp_name   s(    W%Nc'l]++r/   c                     |dz   S )Nz.ytdlr[   r   s     r-   ytdl_filenamezFileDownloader.ytdl_filename   s    '!!r/   F)fatalc                f      fdfd}t        j                  t         j                  |      S )Nc                    t        j                  | ||j                  fdrd nfdj                  j	                  di       j	                  d            S )Nc                 \    t        j                  d      j                  d d|        fS )Ng{Gz?z[download] Unable to  file: )r(   r   r?   eactionfds    r-   <lambda>zIFileDownloader.wrap_file_access.<locals>.error_callback.<locals>.<lambda>   s1    

4 0",,AVW]V^^efgeh?i2jk r/   c                 2    j                  d d|        S )Nz
Unable to r   r2   r   s    r-   r   zIFileDownloader.wrap_file_access.<locals>.error_callback.<locals>.<lambda>   s!    2??ZPVxW^_`^aCb3c r/   retry_sleep_functionsfile_access)infowarnerror
sleep_func)r   report_retry_FileDownloader__to_screenr    r$   )errcountru   r   r   r   s      `r-   error_callbackz7FileDownloader.wrap_file_access.<locals>.error_callback   sN    ,,UG"..k#d)c99==)@"EII-X	Z Zr/   c                 >   t        | j                  j                  dd      |       D ]  }	  || g|i |c S  y # t        $ rU}|j                  t        j
                  t        j                  fv r||_        Y d }~U|j                  |dd       Y d }~md }~ww xY w)Nfile_access_retries   )r      r   )	r   r    r$   OSErrorerrnoEACCESEINVALr   r   )r+   r<   r@   kwargsretryr   r   s         r-   wrapperz0FileDownloader.wrap_file_access.<locals>.wrapper   s    %dkkoo6KQ&OQ_dhi 446t6v664  4yyU\\5<<$@@&) ((a33	4s   >	B3B?BB)	functoolspartialpartialmethod)r   r   r   r   s   `` @r-   wrap_file_accesszFileDownloader.wrap_file_access   s)    	Z	4   !8!8'BBr/   openTc                     t        ||      \  }}t        |dd       s$| j                  t        j                   dd       ||fS )Nlockedz. Proceeding without lockingT)	only_once)r   r;   r8   r
   msg)r+   r   	open_modefs       r-   r   zFileDownloader.sanitize_open   sL    #Hi88q(D) 7 ; ;<<XYeij({r/   removec                 n    t         j                  j                  |      rt        j                  |       y y r_   )rx   ry   rz   r   r   s     r-   
try_removezFileDownloader.try_remove  s#    77>>(#IIh $r/   renamec                 <    ||k(  ry t        j                  ||       y r_   )rx   replace)r+   old_filenamenew_filenames      r-   
try_renamezFileDownloader.try_rename
  s    <'


<.r/   c                 D   |yt         j                  j                  t        |            sy|}|yt	        |      }||S |dk(  ryt        j                  t              5  t        j                  |t        j                         |f       ddd       |S # 1 sw Y   |S xY w)z4Try to set the last-modified time of the given file.Nr   )
rx   ry   rz   r   r   
contextlibsuppress	Exceptionutimer(   )r+   r   last_modified_hdrtimestrfiletimes        r-   	try_utimezFileDownloader.try_utime  s    $ww~~nX67#?w'Oq=  + 	8HHX		X67	8	8s    +BBc                 ,    | j                  d|z          y)zReport destination filename.z[download] Destination: Nr?   r   s     r-   report_destinationz!FileDownloader.report_destination#  s    1H<=r/   c                 &   | j                   j                  d      rt               | _        n| j                  j                   j                  d      r)t        | j                  j                   d   |      | _        n| j                   j                  d      r0t        | j                  j                  j                  |      | _        nJt        | j                  j                  j                  || j                   j                  d             | _        | j                  j                  j                  xr# | j                  j                  j                  dk7  | j                  _        | j                  j                  j                  | j                  _        y )N
noprogressloggerprogress_with_newliner>   no_color)r    r$   r   
_multiliner,   r   r   
_out_filesoutr   _allow_colorsallow_colors_HAVE_FULLCAP)r+   liness     r-   r!   z(FileDownloader._prepare_multiline_status'  s   ;;??<(35DOXX__  *-dhhooh.GODO[[__454TXX5H5H5L5LeTDO.txx/B/B/F/FSWS^S^SbSbcjSkOklDO'+xx'='='A'A'ndhhF\F\F`F`dnFn$(,(>(>(B(B%r/   c                 8    | j                   j                          y r_   )r   endr+   s    r-   _finish_multiline_statusz'FileDownloader._finish_multiline_status3  s    r/   z
light blueyellowgreenz
bold white )downloaded_bytesr\   etarq   r   total_bytestotal_bytes_estimatec                 T   | j                   j                  D ](  \  }}d| d}||vr| j                  ||   |      ||<   * ||z  |d<   |j                         }|j	                  d       |d   |d}| j
                  j                  di       }| j                  j                  | j                  j                  |j                  d      xs d|      |j                  d	      xs d
       | j                  | j                  j                  |j                  d      xs d|             y )NrC   _str_default_template	info_dict)r   progressprogress_templatedownloadz)[download] %(progress._default_template)sprogress_idxr   zdownload-titlez%yt-dlp %(progress._default_template)s)ProgressStylesitems__format_progresscopypopr    r$   r   print_at_liner,   evaluate_outtmplr5   )r+   sdefault_templatenamestyleprogress_dictr   s          r-   _report_progress_statusz&FileDownloader._report_progress_status@  s%   ..55 	<KD%tfD>D1}++AdGU;AdG		<
 "2A!5
+&!";]K KKOO,?D%%dhh&?&?!!*-\1\'EE.16Q	8 	dhh77!!"23^7^ 	r/   c                      | j                   j                  | j                  j                  | j                  j                  g|i |S r_   )r,   _format_textr   streamr   )r+   r@   r   s      r-   r   zFileDownloader._format_progressT  sH    $txx$$OO""DOO$@$@SCGSKQS 	Sr/   c                    ddfd
}fd}d   dk(  r| j                   j                  d      r| j                  d       t        fd	      }j	                  || j                  |      j                          |d
      | j                  j                  d            | j                  d      d       | j                  t        d |d       |d       |d      d             d   dk7  ry | j                   j                  d      x}rU| j                  5  t        j                         | j                  k  r
	 d d d        y | xj                  |z  c_        d d d        j	                  | j                  j                  d            j                         | j                  j                  d            | j                  t        fdfdfd             |d
       |d       |d      | j                  j                  d            d        |ddd d!d"      }| |d#d$      z  }| j                  |       y # 1 sw Y   xY w)%Nr   )defaultc                 L    |D ]  ^ }}t        fd|D              s|c S  | S )Nc              3   D   K   | ]  }j                  |      d u  y wr_   )r$   ).0r   r  s     r-   	<genexpr>zFFileDownloader.report_progress.<locals>.with_fields.<locals>.<genexpr>[  s     <quuQxt+<s    )all)r  tupsfieldstmplr  s       r-   with_fieldsz3FileDownloader.report_progress.<locals>.with_fieldsY  s0    !%  <V<<K  Nr/   c                 <    t        j                  |             dS )Nrp   )r   r$   )kr  s    r-   r   z0FileDownloader.report_progress.<locals>.<lambda>_  s    \!%%(%;D$A r/   statusfinishedr   z[download] Download completedc                       d    d   z  S )Nr   r   r[   r  s   r-   r   z0FileDownloader.report_progress.<locals>.<lambda>d  s    Q}%5)%D r/   r   r   d   )rq   
_speed_str_total_bytes_str_elapsed_str_percent_strz100%%)r   zof %(_total_bytes_str)s)r   zin %(_elapsed_str)s)rq   zat %(_speed_str)s )delimdownloadingr   r   rq   c                       d d   z   d   z  S )Nr  r   r   r[   r  s   r-   r   z0FileDownloader.report_progress.<locals>.<lambda>  s    a 233a6FF r/   c                       d d   z   d   z  S )Nr  r   r   r[   r  s   r-   r   z0FileDownloader.report_progress.<locals>.<lambda>  s    a 233a8N6OO r/   c                       d   dk(  xr dS )Nr   r   r[   r  s   r-   r   z0FileDownloader.report_progress.<locals>.<lambda>  s    ,-28q r/   r   r   )_eta_strr   r#  r!  _total_bytes_estimate_str_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   r   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_indexfragment_countz- (frag %(fragment_index)s/%(fragment_count)s))r-  z (frag %(fragment_index)s))r    r$   r?   r   updaterr   striprP   r]   r
  r   r'   r(   r)   r*   rR   )r+   r  r  _format_bytesrq   update_deltamsg_templates    `     r-   r#   zFileDownloader.report_progressX  s4   ') 	 CX;*${{|,>?DEEHH"//6<<>$1-$@ $ 3 3AEE)4D E $ 3 3C 8  ((MFG>?:;-  X;-';;??+;<<<<** :>>#d&?&??: : ))\9):
 	
e5;;=++AEE'N; //FO81: ; !.m <)67M)N%23E%F //i0@A
 	 #j}mOIK 	a<> 	> 	$$Q59: :s   #IIIc                 ,    | j                  d|z         y)z'Report attempt to resume at given byte.z'[download] Resuming download at byte %sNr   )r+   
resume_lens     r-   report_resuming_bytez#FileDownloader.report_resuming_byte  s    @:MNr/   c                 
    |t         u rdnd}t        j                  ||| j                   fd|st        n fd j
                  j                  di       j                  |xs d      |rd|dnd	|  
       yd
       y)zReport retryFfragmentc                 ,    j                  d|        S )Nz[download] Got error: )r   )r   r+   s    r-   r   z-FileDownloader.report_retry.<locals>.<lambda>  s    T--0Fse.LM r/   c                 ,    j                  d|        S )Nz[download] Got error: r   )r   r+   s    r-   r   z-FileDownloader.report_retry.<locals>.<lambda>  s    t7H7HKcdecfIg7h r/   r   httpNr  r$  )r   r   r   r   suffix)r	   r   r   r   r   r    r$   )r+   r   r   ru   
frag_indexr   is_frags   `      r-   r   zFileDownloader.report_retry  s    %3%!!d&6&6M"'(-h{{'>CGGHYSYZSZXZ%7cq=MNO	f
 ae	fr/   c                 &    | j                  d       y)z,Report it was impossible to resume download.z[download] Unable to resumeNr   r   s    r-   report_unable_to_resumez&FileDownloader.report_unable_to_resume  s    45r/   c                      y)zp Whether the downloader can download the fragments from the manifest.
        Redefine in subclasses if needed. Nr[   )manifests    r-   supports_manifestz FileDownloader.supports_manifest  s     	r/   c           	         | j                   j                  dd       xr( t        j                  j	                  t        |            }t        |d      s| j                   j                  dd      xrG t        j                  j                  t        |            xr | j                   j                  dd       }|dk7  rb|s|r^| j                  |       | j                  |dt        j                  j                  t        |            d	|       | j                          y
|r | j                   j                  d      xs d}nR| j                   j                  d      xs d}t        j                  || j                   j                  d      xs |      }|dkD  r+| j                  d|dd       t        j                   |       | j#                  ||      }| j                          |dfS )zpDownload to a filename using the info from info_dict
        Return True on success and False otherwise
        
overwritesTwrite
continuedlr   Fr   r  )r   r  r   )TFsleep_interval_subtitlesr   sleep_intervalmax_sleep_intervalz[download] Sleeping z.2fz seconds ...)r    r$   rx   ry   r   r   r9   rz   r3   _hook_progressr{   r   randomuniformr?   r(   r   real_download)	r+   r   r   subtitlenooverwrites_and_existscontinuedl_and_existsrI  min_sleep_intervalrets	            r-   r   zFileDownloader.download  s   
 d33 9~h78 	 
 x)d3 9GGNN>(#;<9%88 " 3$;?T33H=## ((#%77??>(3K#L% 	
 --/"![[__-GHMAN!%1A!B!Ga#^^"DKKOO4H$I$_M_aNANN1.1E\RSJJ~&  95%%'Dyr/   c                     t        d      )z.Real download process. Redefine in subclasses.z-This method must be implemented by subclasses)NotImplementedError)r+   r   r   s      r-   rN  zFileDownloader.real_download  s    !"QRRr/   c                 @    ||d<   | j                   D ]
  } ||        y )Nr   )r   )r+   r  r   phs       r-   rK  zFileDownloader._hook_progress  s*    '{ && 	BvJ	r/   c                 :    | j                   j                  |       y r_   )r   append)r+   rW  s     r-   r"   z FileDownloader.add_progress_hook  s     	##B'r/   c                     | j                   j                  dd      sy |D cg c]  }t        |       }}|"t        j                  j                  |d         }| j                  | dt        |              y c c}w )NverboseFr   z command line: )r    r$   r   rx   ry   basenamer8   r   )r+   r@   exeastr_argss        r-   
_debug_cmdzFileDownloader._debug_cmd  sp    {{y%0/34!N1%44;''""8A;/CC5H0E/FGH 5s   A:)r   )Fr_   )4rG   
__module____qualname____doc___TEST_FILE_SIZEr    r.   r   r?   r   r   rJ   staticmethodrP   classmethodrR   rX   r]   r	   rj   ra   rr   rv   r}   r   r   r   r   r   r   r   r   r   r   r   r   r!   r   r   r   r
  r   r#   r6  r   r@  rC  r   rN  rK  r"   r`  r[   r/   r-   r   r   &   s'   *X OF	98"K KN N , , I I = =
 D D =GQ[ D D " " T T B B  
 
 
 $ $' "
" +0 C( fD) * h     h/  /
&>
C %N(S;6zO <FT f6  
'RS(
	Ir/   r   )!r   r   r   rx   rL  rE   r%   r(   
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-   <module>ri     sN       	  	       ,KI KIr/   