
    V|hmP                         S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKrSSKJ	r	J
r
JrJr  SSKJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKJr   " S S5      r g)    N   )BreaklineStatusPrinterMultilineLoggerMultilinePrinterQuietMultilinePrinter)IDENTITY
NO_DEFAULTLockingUnsupportedError	NamespaceRetryManagerclasspropertydeprecation_warningformat_bytesjoin_nonemptyparse_bytesremove_startsanitize_openshell_quotetimeconverttimetuple_from_msectry_call)_ProgressStatec            
          \ rS rSrSrSrSrS rS rS r	\	r
\S 5       r\S	 5       r\S
 5       r\S 5       r\S 5       r\\\4S j5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       rS rS rS rS rSS.S jr\" SSS9S 5       r \" S5      S 5       r!\" S 5      S! 5       r"S" r#S# r$S:S$ jr%S% r&\'" S&S&S'S(S)S*S*S+9r(S, r)S- r*S. r+S/ r,\S4S0 jr-S1 r.\S2 5       r/S;S3 jr0S4 r1S5 r2S6 r3S<S7 jr4S8 r5S9r6g)=FileDownloader%   ap  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
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                 @   U R                  U5        / U l        X l        U R                  5         U R	                  U R
                  5        U R                  R                  S5      (       a5  [        R                  " 5       U l	        [        R                  " 5       U l        gg)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      R/home/james-whalen/.local/lib/python3.13/site-packages/yt_dlp/downloader/common.py__init__FileDownloader.__init__T   sr    c!&&(t334;;??+,,(1(8D%(,(8D% -    c           	      p    Xl         S H*  n[        X5      (       a  M  [        X[        X5      5        M,     g )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   FileDownloader._set_ydl_   s/    

D 4&&GC$67

r0   c                 r    U R                   R                  " USU R                  R                  S5      0UD6  g )Nquiet)r,   	to_screenr    r$   )r+   argskargss      r-   rA   FileDownloader.to_screenp   s+    DJ(@JEJr0   c                 h    [         R                  " SSU R                  S S 5      R                  5       $ )Nz(?<=[a-z])(?=[A-Z])_)resub__name__lower)clss    r-   FD_NAMEFileDownloader.FD_NAMEu   s*    vv,c3<<3DEKKMMr0   c                 X    U c  g[        U S-  5      nUR                  S:  a  gSUS S -  $ )Nz Unknowni  c   z--:--:--z%02d:%02d:%02d)r   hours)secondsr(   s     r-   format_secondsFileDownloader.format_secondsy   s7    ?"7T>2::?$s)++r0   c                 <    [        U R                  U5      S5      S $ )Nz00:z>8s)r   rT   )rL   rS   s     r-   
format_etaFileDownloader.format_eta   s    s11':EB3GHr0   c                 >    Uc  g [        U 5      [        U5      -  S-  $ )N      Y@float)byte_counterdata_lens     r-   calc_percentFileDownloader.calc_percent   s$    \"U8_4u<<r0   c                     U c  S$ U S S3$ )Nz  N/A%z>5.1f% )percents    r-   format_percentFileDownloader.format_percent   s    "?xC75/0CCr0   c                    U[         L a!  XpeS XV4;   a  g [        [        U5      U-  5      $ XpUc  g Uc  [        R                  " 5       nU R	                  XxU5      nU=(       a#    [        [        U5      [        U5      -
  U-  5      $ N)r	   intr\   r(   
calc_speed)	rL   start_or_ratenow_or_remainingtotalcurrentrate	remainingstartnows	            r-   calc_etaFileDownloader.calc_eta   s    J+)((uY'$.//"s=;))+C~~e'2CU5\E'N:dBCCr0   c                 @    X-
  nUS:X  d  US:  a  g [        U5      U-  $ )Nr   MbP?r[   )rq   rr   bytesdifs       r-   rj   FileDownloader.calc_speed   s(    kA:uU|c!!r0   c                 *    U c  S$ [        U 5      S S3$ )Nz Unknown B/s>10sz/s)r   )speeds    r-   format_speedFileDownloader.format_speed   s!    !&~S|E7J46PPR4SSr0   c                 :    U [        S5      :X  a  S$ [        U 5      $ )Ninf)r\   ri   )retriess    r-   format_retriesFileDownloader.format_retries   s    5</uAS\Ar0   c                     [         R                  R                  U 5      (       a  [         R                  R                  U 5      $ g)Nr   )ospathisfilegetsize)unencoded_filenames    r-   filesize_or_noneFileDownloader.filesize_or_none   s-    77>>,--77??#566r0   c                     [        US-  S5      n[        [        US-  S5      S5      nU S:  a  [        U5      $ X-  nXC:  a  [        U5      $ XB:  a  [        U5      $ [        U5      $ )Ng       @g      ?i  @ rv   )maxminri   )elapsed_timerw   new_minnew_maxro   s        r-   best_block_sizeFileDownloader.best_block_size   sk    eck3'c%#+s+W5%w<#>w<>w<4yr0   c                 .    [        S5        [        U 5      $ )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   FileDownloader.parse_bytes   s     	 a 	b7##r0   c                    U R                   R                  S5      nUb  US:X  a  gUc  [        R                  " 5       nX!-
  nUS::  a  g[        U5      U-  nXd:  a/  [        U5      U-  U-
  nUS:  a  [        R                  " U5        ggg)z3Sleep if the download speed is over the rate limit.	ratelimitNr   g        )r    r$   r(   r\   sleep)r+   
start_timerr   r]   
rate_limitelapsedr|   
sleep_times           r-   	slow_downFileDownloader.slow_down   s    [[__[1
!2;))+C"c>l#g-|,z9GCJA~

:&  r0   c                     U R                   R                  SS5      (       dN  US:X  dH  [        R                  R	                  U5      (       a&  [        R                  R                  U5      (       d  U$ US-   $ )z4Returns a temporary filename for the given filename.nopartF-.part)r    r$   r   r   existsr   r+   filenames     r-   	temp_nameFileDownloader.temp_name   sR    ;;??8U++x3))"''..2J2JO'!!r0   c                 P    UR                  S5      (       a  US [        S5      *  $ U$ )Nr   )endswithlenr   s     r-   undo_temp_nameFileDownloader.undo_temp_name   s+    W%%Nc'l]++r0   c                     US-   $ )Nz.ytdlrc   r   s     r-   ytdl_filenameFileDownloader.ytdl_filename   s    '!!r0   F)fatalc                l   ^ ^^ U U4S jmU4S jn[         R                  " [         R                  U5      $ )Nc                   >^ [         R                  " XUTR                  UU4S jT(       a  S OUU4S jTR                  R	                  S0 5      R	                  S5      S9$ )Nc                 ^   > [         R                  " S5      TR                  ST SU  35      4$ )Ng{Gz?z[download] Unable to  file: )r(   r   rA   eactionfds    r-   <lambda>IFileDownloader.wrap_file_access.<locals>.error_callback.<locals>.<lambda>   s/    

4 0",,AVW]V^^efgeh?i2jkr0   c                 2   > TR                  ST SU  35      $ )Nz
Unable to r   r3   r   s    r-   r   r      s    2??ZPVxW^_`^aCb3cr0   retry_sleep_functionsfile_access)infowarnerror
sleep_func)r   report_retry_FileDownloader__to_screenr    r$   )errcountr   r   r   r   s      `r-   error_callback7FileDownloader.wrap_file_access.<locals>.error_callback   sL    ,,G"..k#d)c99==)@"EII-X	Z Zr0   c                 B  > [        U R                  R                  SS5      TU S9 H  n U" U /UQ70 UD6s  $    g ! [         aX  nUR                  [        R
                  [        R                  4;   a  XTl         S nAMY  UR                  USS5         S nAMr  S nAff = f)Nfile_access_retries   )r      r   )	r   r    r$   OSErrorerrnoEACCESEINVALr   r   )r+   r=   rB   kwargsretryr   r   s         r-   wrapper0FileDownloader.wrap_file_access.<locals>.wrapper   s    %dkkoo6KQ&OQ_dhi46t6v66 j  4yyU\\5<<$@@&) ((a33	4s   <
B4B BB)	functoolspartialpartialmethod)r   r   r   r   s   `` @r-   wrap_file_accessFileDownloader.wrap_file_access   s)    	Z	4   !8!8'BBr0   openTc                     [        X5      u  p1[        USS 5      (       d!  U R                  [        R                   S3SS9  X14$ )Nlockedz. Proceeding without lockingT)	only_once)r   r<   r9   r
   msg)r+   r   	open_modefs       r-   r   FileDownloader.sanitize_open   sI    #H8q(D)) 7 ; ;<<XYeij{r0   removec                 z    [         R                  R                  U5      (       a  [         R                  " U5        g g rh   )r   r   r   r   r   s     r-   
try_removeFileDownloader.try_remove  s&    77>>(##IIh $r0   renamec                 <    X:X  a  g [         R                  " X5        g rh   )r   replace)r+   old_filenamenew_filenames      r-   
try_renameFileDownloader.try_rename  s    '


<.r0   c                 T   Uc  g[         R                  R                  U5      (       d  gUnUc  g[        U5      nUc  U$ US:X  a  g[        R
                  " [        5         [         R                  " U[        R                  " 5       U45        SSS5        U$ ! , (       d  f       U$ = f)z4Try to set the last-modified time of the given file.Nr   )	r   r   r   r   
contextlibsuppress	Exceptionutimer(   )r+   r   last_modified_hdrtimestrfiletimes        r-   	try_utimeFileDownloader.try_utime  s    $ww~~h''#?w'Oq=  +HHX		X67 , ,+s   !-B
B'c                 ,    U R                  SU-   5        g)zReport destination filename.z[download] Destination: NrA   r   s     r-   report_destination!FileDownloader.report_destination!  s    1H<=r0   c                 T   U R                   R                  S5      (       a  [        5       U l        OU R                  R                   R                  S5      (       a)  [        U R                  R                   S   U5      U l        OU R                   R                  S5      (       a0  [        U R                  R                  R                  U5      U l        OM[        U R                  R                  R                  XR                   R                  S5      (       + 5      U l        U R                  R                  R                  =(       a#    U R                  R                  R                  S:g  U R                  l        U R                  R                  R                  U R                  l        g )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!   (FileDownloader._prepare_multiline_status%  s   ;;??<((35DOXX__  **-dhhooh.GODO[[__4554TXX5H5H5L5LeTDO.txx/B/B/F/FS^S^SbSbcjSkOklDO'+xx'='='A'A'ndhhF\F\F`F`dnFn$(,(>(>(B(B%r0   c                 8    U R                   R                  5         g rh   )r  endr+   s    r-   _finish_multiline_status'FileDownloader._finish_multiline_status1  s    r0   z
light blueyellowgreenz
bold white )downloaded_bytesrd   etar|   r   total_bytestotal_bytes_estimatec                    U R                   R                   H(  u  p4SU S3nX1;  a  M  U R                  X   U5      X'   M*     X!-  US'   UR                  5       nUR	                  S5        US   US.nU R
                  R                  S0 5      nU R                  R                  U R                  R                  UR                  S5      =(       d    SU5      UR                  S	5      =(       d    S
5        U R                  U R                  R                  UR                  S5      =(       d    SU5      [        R                  " U5      UR                  S5      5        g )NrF   _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_percent)ProgressStylesitems__format_progresscopypopr    r$   r  print_at_liner,   evaluate_outtmplr6   r   	from_dict)r+   sdefault_templatenamestyleprogress_dictr  s          r-   _report_progress_status&FileDownloader._report_progress_status>  s0   ..55KDtfD>D}++AGU;AG	 6
 "2!5
+&!";]K KKOO,?D%%dhh&?&?!!*-\1\'EE.16Q	8 	dhh77!!"23^7^*44Q7z9J	Lr0   c                     U R                   R                  " U R                  R                  U R                  R                  /UQ70 UD6$ rh   )r,   _format_textr  streamr  )r+   rB   r   s      r-   r   FileDownloader._format_progressR  sF    xx$$OO""DOO$@$@SCGSKQS 	Sr0   c                   ^ SS.U4S jjnU4S jnTS   S:X  a  U R                   R                  S5      (       a  U R                  S5        [        U4S	 j5      nTR	                  UU R                  U5      R                  5       U" S
5      U R                  TR                  S5      5      SU R                  S5      S.5        U R                  T[        SU" S5      U" S5      U" S5      SS95        TS   S:w  a  g U R                   R                  S5      =n(       aW  U R                     [        R                  " 5       U R                  :  a
   S S S 5        g U =R                  U-  sl        S S S 5        [        U4S jU4S jU4S j5      nTR	                  U R                  TR                  S5      5      R                  5       U R                  TR                  S5      5      UU R                  U5      U" S
5      U" S5      U" S5      U R                  TR                  S5      5      S.5        U" SS S!S"S#S9nXr" S$S%5      -  nU R                  TU5        g ! , (       d  f       N= f)&Nr  )defaultc                 Z   > U H#  Gt p#[        U4S jU 5       5      (       d  M!  Us  $    U $ )Nc              3   J   >#    U  H  nTR                  U5      S Lv   M     g 7frh   )r$   ).0r   r&  s     r-   	<genexpr>FFileDownloader.report_progress.<locals>.with_fields.<locals>.<genexpr>Y  s     <VquuQxt+Vs    #)all)r2  tupsfieldstmplr&  s       r-   with_fields3FileDownloader.report_progress.<locals>.with_fieldsW  s,    !%<V<<<K "& Nr0   c                 <   > [        TR                  U 5      5      S $ )Nr{   )r   r$   )kr&  s    r-   r   0FileDownloader.report_progress.<locals>.<lambda>]  s    \!%%(%;D$A"Br0   statusfinishedr   z[download] Download completedc                     > T S   T S   -  $ )Nr  r   rc   r&  s   r-   r   r@  b  s    Q}%5)%Dr0   r  r   rZ   d   )r|   
_speed_str_total_bytes_str_elapsed_strr  _percent_strz100%%)r  zof %(_total_bytes_str)s)r   zin %(_elapsed_str)s)r|   zat %(_speed_str)s )delimdownloadingr   c                      > ST S   -  T S   -  $ )NrE  r  r  rc   rD  s   r-   r   r@  |  s    C!.//!M2BBr0   c                      > ST S   -  T S   -  $ )NrE  r  r  rc   rD  s   r-   r   r@  }  s    C!.//!4J2KKr0   c                  &   > T S   S:H  =(       a    S$ )Nr  r   rc   rD  s   r-   r   r@  ~  s    A()Q.414r0   r  r|   r  r  )_eta_strrF  r  rI  rG  _total_bytes_estimate_str_downloaded_bytes_strrH  )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))rS  z (frag %(fragment_index)s))r    r$   rA   r   updater}   striprT   re   r+  r   r'   r(   r)   r*   rW   )r+   r&  r<  _format_bytesr|   update_deltar  msg_templates    `      r-   r#   FileDownloader.report_progressV  s<   ') 	 	 CX;*${{|,,>?DEEHH"//6<<>$1-$@ $ 3 3AEE)4D E! $ 3 3C 8  ((MFG>?:;-  X;-';;??+;<<<<**>>#d&?&?? +* ))\9) +
 BK46 	
e5;;=++AEE'N;  //9 -m <)67M)N%23E%F //i0@A	
 		 #j}mOIK 	a<> 	> 	$$Q5= +*s   *%II
I'c                 ,    U R                  SU 35        g)z'Report attempt to resume at given byte.z%[download] Resuming download at byte Nr   )r+   
resume_lens     r-   report_resuming_byte#FileDownloader.report_resuming_byte  s    >zlKLr0   c                   ^  U[         L a  SOSn[        R                  " XUT R                  U 4S jU(       d  [        OU 4S jT R
                  R                  S0 5      R                  U=(       d    S5      U(       a  SUc  SOS	U 3 3OSS
9  g)zReport retryFfragmentc                 ,   > TR                  SU  35      $ )Nz[download] Got error: )r   )r   r+   s    r-   r   -FileDownloader.report_retry.<locals>.<lambda>  s    T--0Fse.LMr0   c                 ,   > TR                  SU  35      $ )Nz[download] Got error: r   )r   r+   s    r-   r   rb    s    t7H7HKcdecfIg7hr0   r   httpNr&  rJ  )r   r   r   r   suffix)r	   r   r   r   r   r    r$   )r+   r   r   r   
frag_indexr   is_frags   `      r-   r   FileDownloader.report_retry  sz    %3%!!d&6&6M"'(-h{{'>CGGHYSYZSZXZ%7cq=MNO`d	fr0   c                 &    U R                  S5        g)z,Report it was impossible to resume download.z[download] Unable to resumeNr   r  s    r-   report_unable_to_resume&FileDownloader.report_unable_to_resume  s    45r0   c                     g)zgWhether the downloader can download the fragments from the manifest.
Redefine in subclasses if needed. Nrc   )manifests    r-   supports_manifest FileDownloader.supports_manifest  s     	r0   c                    U R                   R                  SS5      (       + =(       a    [        R                  R	                  U5      n[        US5      (       d  U R                   R                  SS5      =(       aG    [        R                  R                  U5      =(       a!    U R                   R                  SS5      (       + nUS:w  ac  U(       d  U(       aU  U R                  U5        U R                  US[        R                  R                  U5      S	.U5        U R                  5         g
SnU(       a%  U R                   R                  S5      =(       d    SnOU R                   R                  S5      =(       d    SnU R                   R                  S5      =(       d    Sn	UR                  S5      =n
(       a1  U
[        [        R                  " 5       5      -
  nX:  a  SnUnX:  a  Un	[        R                  " X=(       d    U5      nUS:  a/  U R                  SUS SU S35        [        R                   " U5        U R#                  X5      nU R                  5         US4$ )z`Download to a filename using the info from info_dict
Return True on success and False otherwise

overwritesTwrite
continuedlr   Fr   rB  )r   rA  r  )TFr  sleep_interval_subtitlesr   sleep_intervalmax_sleep_intervalavailable_atzas required by the sitez[download] Sleeping z.2fz	 seconds z...)r    r$   r   r   r   r:   r   r4   _hook_progressr   r  ri   r(   randomuniformrA   r   real_download)r+   r   r  subtitlenooverwrites_and_existscontinuedl_and_exists
sleep_noteru  min_sleep_intervalrv  rw  forced_sleep_intervalrets                r-   r  FileDownloader.download  s   
 d33 )x( 	 
 x))d3 9GGNN8,9%88 " 3$;?T33H=## ((#%77??8#<% 	
 --/"
![[__-GHMAN!%1A!B!Ga!%1E!F!K!(}}^<<|<(4s499;7G(G%(=!:J)>&(=)>&#^^"$L:LNN ANN1.1EYzlZ]^_JJ~&  5%%'Dyr0   c                     [        S5      e)z.Real download process. Redefine in subclasses.z-This method must be implemented by subclasses)NotImplementedError)r+   r   r  s      r-   r{  FileDownloader.real_download  s    !"QRRr0   c                 B    X!S'   U R                    H  nU" U5        M     g )Nr  )r   )r+   rA  r  phs       r-   rx  FileDownloader._hook_progress  s#    '{ &&BvJ 'r0   c                 :    U R                   R                  U5        g rh   )r   append)r+   r  s     r-   r"    FileDownloader.add_progress_hook  s     	##B'r0   c                     U R                   R                  SS5      (       d  g Uc"  [        R                  R	                  US   5      nU R                  U S[        U5       35        g )NverboseFr   z command line: )r    r$   r   r   basenamer9   r   )r+   rB   exes      r-   
_debug_cmdFileDownloader._debug_cmd  sV    {{y%00;''""47+CC5D0A/BCDr0   c                     UR                  S5      nUc  g U R                  R                  U5      u  p4U(       a  U$ U(       a*  U R                  U R                  R	                  U5      5        g )Nimpersonate)r$   r,   _parse_impersonate_targetsr5   _unavailable_targets_message)r+   r  r  available_targetrequested_targetss        r-   _get_impersonate_target&FileDownloader._get_impersonate_target  s_    mmM2.2hh.Q.QR].^+## E EFW XYr0   )r  r'   r*   r   r    r,   )r   )Frh   )7rJ   
__module____qualname____firstlineno____doc___TEST_FILE_SIZEr    r.   r   rA   r   r   rM   staticmethodrT   classmethodrW   r_   re   r	   rs   rj   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r  r   r  r+  r   r#   r]  r   rj  rn  r  r{  rx  r"   r  r  __static_attributes__rc   r0   r-   r   r   %   s-   )V 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L(S>6@M <FT f6  
3jS(
E	r0   r   )!r   r   r   r   ry  rH   r%   r(   
minicursesr   r   r   r   utilsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   utils._utilsr   r   rc   r0   r-   <module>r     sQ       	  	       $ *b br0   