o
    bP7                     @   s   d dl Z d dlZd dlZd dlZd dlZdddZdadadddZG dd	 d	Z	G d
d dZ
dd Zdd ZG dd de
ZG dd dZdddZdd ZdS )    N   c                 C   sD   zd}t | tj|}td|d }|pdW S  ty!   Y dS w )z Get the real terminal width abcdefghhhhhr   P   )fcntlioctltermios
TIOCGWINSZstructunpackIOError)fdbufret r   1/usr/share/virt-manager/virtinst/_progresspriv.pyterminal_width   s   
r         ?c                 C   s,   t   }tdu s|t |krt| a|atS )z6 Get the real terminal width, but cache it for a bit. N)time_term_width_val_term_width_lastr   )r   cache_timeoutnowr   r   r   terminal_width_cached$   s
   r   c                   @   s>   e Zd ZdZdddZdd	 ZdddZdddZdd ZdS )TerminalLinezB Help create dynamic progress bars, uses terminal_width_cached(). r   Nr   r   c                 C   s.   |d u r|}|| _ tt|||| _d| _d S )NF)_min_lenmaxr   llen_fin)selfmin_restbeg_lenr   r   r   r   r   __init__3   s
   
zTerminalLine.__init__c                 C      | j | j S )z Usable length for elements. )r   r   r   r   r   r   __len__:      zTerminalLine.__len__   c                 C   s   t | j| d| S )zw After a fixed length, split the rest of the line length among
            a number of different elements (default=2). r   )r   r   )r   fixedelementsr   r   r   
rest_split>   s   zTerminalLine.rest_splitc                 C   sB   |du rt |}t | |k rd| _| jrdS |  jt |8  _|S )z If there is room left in the line, above min_len, add element.
            Note that as soon as one add fails all the rest will fail too. NT )lenr   r   )r   elementfull_lenr   r   r   addC   s   zTerminalLine.addc                 C      | j S )zA Current rest of line, same as .rest_split(fixed=0, elements=1). )r   r$   r   r   r   restQ      zTerminalLine.rest)r   Nr   r   )r'   N)	__name__
__module____qualname____doc__r"   r%   r*   r/   r1   r   r   r   r   r   0   s    


r   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )	BaseMeterc                 C   s0   d| _ d | _d | _d | _d| _d | _t | _d S )Ng333333?r   )update_periodtextsize
start_timelast_amount_readlast_update_timeRateEstimatorrer$   r   r   r   r"   W   s   zBaseMeter.__init__c                 C   s^   || _ || _t|ttd fv sJ | j d usJ t }|| _| j|| d| _|| _	d S Nr   )
r:   r;   typeintr   r<   r@   startr=   r>   )r   r:   r;   r   r   r   r   rD   a   s   
zBaseMeter.startc                 C   sZ   t |tu sJ t }| jr|| j| j kr+| j|| || _|| _| | d S d S r3   )	rB   rC   r   r>   r9   r@   updater=   
_do_update)r   amount_readr   r   r   r   rE   m   s   zBaseMeter.updatec                 C      d S r3   r   )r   rG   r   r   r   rF   z      zBaseMeter._do_updatec                 C   s   |    d S r3   )_do_endr$   r   r   r   end}   s   zBaseMeter.endc                 C   rH   r3   r   r$   r   r   r   rJ      rI   zBaseMeter._do_endN)	r4   r5   r6   r"   rD   rE   rF   rK   rJ   r   r   r   r   r8   V   s    
r8   c                 C   s@   || }t |}d| }|| dkr|d7 }| d|||f S )N=g      ?-z	 [%-*.*s])rC   r/   )tlbar_max_lengthpcbar_lenibar_lenprogressbarr   r   r   _term_add_bar   s   
rT   c                 C   s>   |r||kr|  ddfS ||kr|  ddfS |  ddfS )Nz !!! Tz ...      F)r/   )rN   osizer;   r   r   r   _term_add_end   s   rW   c                   @   s*   e Zd ZejfddZdd Zdd ZdS )	TextMeterc                 C   s   t |  || _d S r3   )r8   r"   output)r   rY   r   r   r   r"      s   

zTextMeter.__init__c              
   C   sL  | j  }t|}t| j  }tdd}t|jdk}|d| }| jd u rO|dt	|| }|d}	|d| }
d|
 |
 | j|
|||	f }nJ| j  }t	||}| j  }|d| }|d	}	|d
|d  }|d| }
d|d }t|||}d|
 |
 | j|||
|||	f	 }| j| | j  d S )N      r    | %5sB  %srU   z %5sB/sz%-*.*s%s%s%s%sz ETA z %2i%%d         z%-*.*s%s%s%s%s%s%s)r@   elapsed_timeformat_numberaverage_rater   boolr   r/   r;   format_timer1   r:   remaining_timefraction_readr*   rT   rY   writeflush)r   rG   etimefreadave_dlrN   	use_hoursui_sizeui_timeui_endui_rateoutrtimefrtimefracui_pcblenui_barr   r   r   rF      s:   







zTextMeter._do_updatec                 C   s   | j }t|}td}t|jdk}|d| }|dt| j | }t	|| j
|\}}|}	d| | | j|||f }
| j|
 | j  d S )NrZ   r   r\   r]   z%-*.*s%s%s%s
)r=   rb   r   rd   r   r/   re   r@   ra   rW   r;   r1   r:   rY   rh   ri   )r   rG   
total_sizerN   rm   rn   ro   rp   not_donedummyrr   r   r   r   rJ      s   zTextMeter._do_endN)r4   r5   r6   sysstderrr"   rF   rJ   r   r   r   r   rX      s    'rX   c                   @   sV   e Zd Zd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S )r?         @c                 C   s(   || _ d | _d | _d | _d| _d | _d S rA   )	timescaletotalr<   r>   r=   ave_rate)r   r   r   r   r   r"   	  s   
zRateEstimator.__init__c                 C   s"   || _ || _|| _d| _d | _d S rA   )r   r<   r>   r=   r   )r   r   r   r   r   r   rD     s
   
zRateEstimator.startc                 C   sh   |dks	|| j k r|| _|| _ d | _d S || j }|| j  }| j r/|| _| ||| j| j| _|| _ d S rA   )r=   r>   r   _temporal_rolling_aver   )r   rG   r   	time_diff	read_diffr   r   r   rE     s   


zRateEstimator.updatec                 C   r0   )z/get the average transfer rate (in bytes/second))r   r$   r   r   r   rc   +  r2   zRateEstimator.average_ratec                 C   r#   )zEthe time between the start of the transfer and the most recent update)r>   r<   r$   r   r   r   ra   /  r&   zRateEstimator.elapsed_timec                 C   s"   | j r| jsdS | j| j | j  S )zestimated time remainingN)r   r   r=   r$   r   r   r   rf   3  s   zRateEstimator.remaining_timec                 C   s,   | j du rdS | j dkrdS t| j| j  S )z[the fraction of the data that has been read
        (can be None for unknown transfer size)Nr   r   )r   floatr=   r$   r   r   r   rg   9  s
   

zRateEstimator.fraction_readc                 C   s   t || d}| ||||S )aq  a temporal rolling average performs smooth averaging even when
        updates come at irregular intervals.  This is performed by scaling
        the "epsilon" according to the time since the last update.
        Specifically, epsilon = time_diff / timescale

        As a general rule, the average will take on a completely new value
        after 'timescale' seconds.r   )min_rolling_ave)r   r   r   last_aver   epsilonr   r   r   r   D  s   z#RateEstimator._temporal_rolling_avec                 C   sP   z|| }W n t y   d}Y nw |du r|S |du r|S || d| |  S )aK  perform a "rolling average" iteration
        a rolling average "folds" new data into an existing average with
        some weight, epsilon.  epsilon must be between 0.0 and 1.0 (inclusive)
        a value of 0.0 means only the old value (initial value) counts,
        and a value of 1.0 means only the newest value is considered.Nr   )ZeroDivisionError)r   r   r   r   r   recent_rater   r   r   r   O  s   zRateEstimator._rolling_aveN)r~   )r4   r5   r6   r"   rD   rE   rc   ra   rf   rg   r   r   r   r   r   r   r?     s    
r?   c                 C   sr   | d u s| dk r|rdS dS | t dkrdS t| } | d }| d } |r3|d }|d }d||| f S d|| f S )	Nr   z--:--:--z--:--infInfinite<   z%02i:%02i:%02iz	%02i:%02i)r   rC   )secondsrm   minuteshoursr   r   r   re   c  s   re   c                 C   s   g d}d}d}d}t |d }| pd} | |kr,||k r,|d }| | } | |kr,||k st| tr4d}n	| dk r;d}nd	}|t| pBdd
|| f S )z4Turn numbers into human-readable metric-like numbers)	r+   kMGTPEZYg      @i  r   r   z%i%s%sgfffff#@z%.1f%s%sz%.0f%s%s )r,   
isinstancerC   r   )numbersymbolsstepthreshdepth	max_depthfmtr   r   r   rb   w  s    

rb   )r   )r   r   )r   )r   r
   r|   r   r   r   r   r   r   r   r8   rT   rW   rX   r?   re   rb   r   r   r   r   <module>   s"   

&^
	A
[