U
    $Pf9                     @   sx   d dl mZm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mZmZmZmZ G dd deZdS )    )divisionunicode_literalsN   )compat_os_name)decodeArgumentencodeFilenameerror_to_compat_strformat_bytesshell_quotetimeconvertc                   @   s\  e Zd ZdZdZdZ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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# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 ZdKd5d6Zd7d8 Z d9d: Z!d;d< Z"d=d> Z#d?d@ Z$dAdB Z%dCdD Z&dEdF Z'dGdH Z(dLdIdJZ)dS )MFileDownloadera6  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.
    retries:            Number of times to retry for HTTP error 5xx
    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.
    logtostderr:        Log messages to stderr instead of stdout.
    consoletitle:       Display progress in console window's titlebar.
    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.
    external_downloader_args:  A list of additional command-line arguments for the
                        external downloader.
    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)

    Subclasses of this one must re-define the real_download method.
    i(  Nc                 C   s"   || _ g | _|| _| | j dS )z6Create a FileDownloader object with the given options.N)ydl_progress_hooksparamsadd_progress_hookreport_progress)selfr   r    r   @/tmp/pip-unpacked-wheel-7zdooeg3/youtube_dl/downloader/common.py__init__=   s    zFileDownloader.__init__c                 C   sN   t | d\}}t |d\}}|dkr(dS |dkr<d||f S d|||f S d S )N<   c   z--:--:--r   z	%02d:%02dz%02d:%02d:%02d)divmod)secondsZminsZsecshoursr   r   r   format_secondsD   s    zFileDownloader.format_secondsc                 C   s    |d krd S t | t | d S )Ng      Y@float)byte_counterZdata_lenr   r   r   calc_percentO   s    zFileDownloader.calc_percentc                 C   s   | d krdS dd|   S )Nz---.-%z%6sz%3.1f%%r   )percentr   r   r   format_percentU   s    zFileDownloader.format_percentc                 C   s\   |d krd S |d krt   }||  }|dks4|dk r8d S t|| }tt|t| | S Nr   MbP?)timer   int)startnowtotalcurrentdifrater   r   r   calc_eta[   s    zFileDownloader.calc_etac                 C   s   | d krdS t | S )Nz--:--)r   r   )etar   r   r   
format_etag   s    zFileDownloader.format_etac                 C   s(   ||  }|dks|dk rd S t || S r"   r   )r&   r'   bytesr*   r   r   r   
calc_speedm   s    zFileDownloader.calc_speedc                 C   s    | d krdd S ddt |   S )Nz%10sz---b/sz%s/s)r	   )speedr   r   r   format_speedt   s    zFileDownloader.format_speedc                 C   s   | t dkrdS d|  S )Ninfz%.0fr   )retriesr   r   r   format_retriesz   s    zFileDownloader.format_retriesc                 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  @ r#   )maxminr%   )Zelapsed_timer/   Znew_minZnew_maxr+   r   r   r   best_block_size~   s    zFileDownloader.best_block_sizec                 C   sN   t d| }|dkrdS t|d}dd|d  }tt|| S )z:Parse a string indicating a byte quantity into an integer.z"(?i)^(\d+(?:\.\d+)?)([kMGTPEZY]?)$N   g      @Z	bkmgtpezyr   )rematchr   groupindexlowerr%   round)ZbytestrZmatchobjnumberZ
multiplierr   r   r   parse_bytes   s    zFileDownloader.parse_bytesc                 O   s   | j j|| d S Nr   	to_screenr   argsZkargsr   r   r   rD      s    zFileDownloader.to_screenc                 C   s   | j | d S rB   rC   r   messager   r   r   	to_stderr   s    zFileDownloader.to_stderrc                 C   s   | j | d S rB   )r   to_console_titlerG   r   r   r   rJ      s    zFileDownloader.to_console_titlec                 O   s   | j j|| d S rB   )r   troublerE   r   r   r   rK      s    zFileDownloader.troublec                 O   s   | j j|| d S rB   )r   report_warningrE   r   r   r   rL      s    zFileDownloader.report_warningc                 O   s   | j j|| d S rB   )r   report_errorrE   r   r   r   rM      s    zFileDownloader.report_errorc                 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   getr$   r   sleep)r   
start_timer'   r   Z
rate_limitelapsedr1   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   rN   ospathexistsr   isfiler   filenamer   r   r   	temp_name   s    zFileDownloader.temp_namec                 C   s    | dr|d td  S |S )NrU   )endswithlenrZ   r   r   r   undo_temp_name   s    
zFileDownloader.undo_temp_namec                 C   s   |d S )Nz.ytdlr   rZ   r   r   r   ytdl_filename   s    zFileDownloader.ytdl_filenamec              
   C   sd   z&||krW d S t t|t| W n8 ttfk
r^ } z| dt|  W 5 d }~X Y nX d S )Nzunable to rename file: %s)rV   renamer   IOErrorOSErrorrM   r   )r   Zold_filenameZnew_filenameerrr   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 zt |t |f W n tk
r|   Y nX |S )z4Try to set the last-modified time of the given file.Nr   )rV   rW   rY   r   r   utimer$   	Exception)r   r[   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rD   rZ   r   r   r   report_destination   s    z!FileDownloader.report_destinationFc                 C   s   d| }| j ddr"| | njtdkrft| dd}|t|krV|d|t|  7 }t|| _d}ntj	 rtd	nd}| j|| | d
 | 
d|  d S )Nz[download] Zprogress_with_newlineFnt!_report_progress_prev_line_lengthr    z[K)Zskip_eolzyoutube-dl )r   rN   rD   r   getattrr^   rl   sysstderrisattyrJ   )r   msgis_last_lineZfullmsgZprev_len
clear_liner   r   r   _report_progress_status   s    
z&FileDownloader._report_progress_statusc                 C   sL  |d dkr| j ddr&| d ndd}|dd k	rPt|d |d< |d	7 }|d
d k	rx| |d
 |d< |d7 }| j|| dd | j drd S |d dkrd S |dd k	r| |d |d< nd|d< |dr|dd k	r| d|d  |d  |d< nd|drL|dd k	rL| d|d  |d  |d< n(|ddkrl| d|d< nd|d< |dd k	r| |d |d< nd|d< |dd k	rt|d |d< d}nt|dd k	rt|d |d< d}nN|dd k	r6t|d |d< |d
r0| |d
 |d< d }nd!}nd"}| ||  d S )#NstatusfinishedZ
noprogressFz[download] Download completedz100%%total_bytesZ_total_bytes_strz of %(_total_bytes_str)srQ   Z_elapsed_strz in %(_elapsed_str)sT)rt   Zdownloadingr-   Z_eta_strzUnknown ETAZdownloaded_bytesd   Z_percent_strZtotal_bytes_estimater   z	Unknown %r1   Z
_speed_strzUnknown speedzK%(_percent_str)s of %(_total_bytes_str)s at %(_speed_str)s ETA %(_eta_str)sZ_total_bytes_estimate_strzU%(_percent_str)s of ~%(_total_bytes_estimate_str)s at %(_speed_str)s ETA %(_eta_str)sZ_downloaded_bytes_strz>%(_downloaded_bytes_str)s at %(_speed_str)s (%(_elapsed_str)s)z+%(_downloaded_bytes_str)s at %(_speed_str)sz5%(_percent_str)s % at %(_speed_str)s ETA %(_eta_str)s)	r   rN   rD   r	   r   rv   r.   r!   r2   )r   sZmsg_templater   r   r   r      sZ       zFileDownloader.report_progressc                 C   s   |  d|  dS )z'Report attempt to resume at given byte.z'[download] Resuming download at byte %sNri   )r   Z
resume_lenr   r   r   report_resuming_byte4  s    z#FileDownloader.report_resuming_bytec                 C   s"   |  dt||| |f  dS )z&Report retry in case of HTTP error 5xxzD[download] Got server HTTP error: %s. Retrying (attempt %d of %s)...N)rD   r   r5   )r   rd   countr4   r   r   r   report_retry8  s
    zFileDownloader.report_retryc                 C   s6   z|  d|  W n tk
r0   |  d Y nX dS )z.Report file has already been fully downloaded.z)[download] %s has already been downloadedz/[download] The file has already been downloadedN)rD   UnicodeEncodeError)r   	file_namer   r   r   report_file_already_downloaded>  s    z-FileDownloader.report_file_already_downloadedc                 C   s   |  d dS )z,Report it was impossible to resume download.z[download] Unable to resumeNri   )r   r   r   r   report_unable_to_resumeE  s    z&FileDownloader.report_unable_to_resumec                 C   s   | j ddotjt|}t|ds| j ddoTtjt|oT| j dd }|dkr|sf|r| | | 	|dtj
t|d	 dS | j d
}|r| j d|}t||}| d| rt|nd|   t| | ||S )zpDownload to a filename using the info from info_dict
        Return True on success and False otherwise
        ZnooverwritesFwriteZ
continuedlTrS   rT   rx   )r[   rw   ry   sleep_intervalmax_sleep_intervalz![download] Sleeping %s seconds...z%.2f)r   rN   rV   rW   rX   r   hasattrrY   r   _hook_progressgetsizerandomuniformrD   
is_integerr%   r$   rO   real_download)r   r[   	info_dictZnooverwrites_and_existsZcontinuedl_and_existsZmin_sleep_intervalr   r   r   r   r   downloadI  s:    


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   r[   r   r   r   r   r   p  s    zFileDownloader.real_downloadc                 C   s   | j D ]}|| qd S rB   )r   )r   rw   phr   r   r   r   t  s    
zFileDownloader._hook_progressc                 C   s   | j | d S rB   )r   append)r   r   r   r   r   r   x  s    z FileDownloader.add_progress_hookc                 C   sR   | j ddsd S dd |D }|d kr8tj|d }| d|t|f  d S )NverboseFc                 S   s   g | ]}t |qS r   )r   ).0ar   r   r   
<listcomp>  s     z-FileDownloader._debug_cmd.<locals>.<listcomp>r   z[debug] %s command line: %s)r   rN   rV   rW   basenamerD   r
   )r   rF   ZexeZstr_argsr   r   r   
_debug_cmd}  s     zFileDownloader._debug_cmd)F)N)*__name__
__module____qualname____doc__Z_TEST_FILE_SIZEr   r   staticmethodr   r   r!   r,   r.   r0   r2   r5   r8   rA   rD   rI   rJ   rK   rL   rM   rR   r\   r_   r`   re   rh   rj   rv   r   r|   r~   r   r   r   r   r   r   r   r   r   r   r   r      s`   %










	
<'r   )
__future__r   r   rV   r:   rp   r$   r   compatr   utilsr   r   r   r	   r
   r   objectr   r   r   r   r   <module>   s    
