+
    Ki!  c                   s    ^ RI t ^ RIt^ RIt^ RIt^ RIHtHtHt ^ RIt^ RI	H
t
 ^ RIHt ^ RIHt ]P                  t ! R R4      tR# )i    N)AnyDictOptional)__version__)jobs)loggerc                   s   a  ] tR t^t o Rt]! ]! ^4      4      w  ttt	t
tRV 3R lR lltR tR tR tRR ltRR	 ltR
 tR tV 3R lR ltR tR tR tV 3R lR ltRtV tR# )
DownloaderzNon-blocking downloader.

Do start() then check_progress() at regular intervals.
Download is done when check_progress() returns 1.0.
Stop with cancel().
Nc                sh   < V ^8  d   QhRS[ RS[ RS[RS[S[ ,          RS[RS[S[ S[ 3,          RR/# )	   urldest	overwritereferercookiesheadersreturnN)strZboolr   r    r   Zformat__classdict__   ";/usr/lib/python3.14/site-packages/lutris/util/downloader.py__annotate__Downloader.__annotate__   s]     !0 !0!0 !0 	!0
 #!0 !0 c3h!0 
!0    c                sv   Wn         W n        WPn        W`n        W0n        W@n        R V n        R V n        V P                  V n	        R V n
        ^ V n        ^ V n        ^ V n        ^ V n        ^ V n        RV n        ^ V n        RV n        . V n        ^ V n        ^ V n        R V n        \.        P0                  ! 4       V n        R # )N00:00:00        )r   r	   r   r   r
   r   stop_requestthreadINITstateerrordownloaded_size	full_sizeprogress_fractionprogress_percentageaverage_speed	time_left	last_sizelast_check_timelast_speedsspeed_check_timetime_left_check_timefile_pointer	threadingZEventprogress_event)selfr   r	   r
   r   r   r   s   &&&&&&&r   __init__ZDownloader.__init__   s     	(  YY

$%()*+ (&) !$%! 'oo/r   c                s(    R V P                   ,          # )zdownloader for %s)r   r,      &r   __repr__ZDownloader.__repr__A   s    "TXX--r   c                s   \         P                  ! RV P                  4       V P                  V n        \        4       V n        V P                  '       dP   \        P                  P                  V P                  4      '       d!   \        P                  ! V P                  4       \        V P                  R4      V n        \        P                   ! V P"                  R4      V n        V P$                  P&                  V n        R# )zStart download job.u   ⬇ %sZwbN)r   debugr   DOWNLOADINGr   get_timer%   r
   ospathisfiler	   removeZopenr)   r   Z	AsyncCallasync_downloadr   r   r.   r/   r   startZDownloader.startD   s    Xtxx(%%
'z>>>bggnnTYY77IIdii  D1nnT%8%8$? KK44r   c                s    V P                   V n        RV n        ^ V n        ^ V n        ^ V n        ^ V n        ^ V n        RV n        ^ V n	        RV n
        . V n        ^ V n        ^ V n        RV n        R# )z!Reset the state of the downloaderNr   r   )r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r.   r/   r   resetZDownloader.resetO   sq    YY

 !"#$ #" !$%! r   c                sp   V'       dm   V P                   V P                  V P                  39   dF   V P                  R8  d5   V P                  P                  4        V P                  P                  4        V P                   V P                  V P                  39  d   V P                  4        V P                  # )zAppend last downloaded chunk to dest file and store stats.

blocking: if true and still downloading, block until some progress is made.
:return: progress (between 0.0 and 1.0)      ?)
r   r   r2   r    r+   ZwaitZclear	CANCELLEDERROR	get_stats)r,   blocking   &&r   check_progressZDownloader.check_progress`   s    
 

tyy$2B2B&CCH^H^adHd$$&%%'::dnndjj99NN%%%r   c                s    V P                   V P                  8X  d'   V P                  RR7       V'       g   K7  V! V 4       KA  V P                  '       d   V P                  hV P                   V P                  8H  # )zBlocks waiting for the download to complete.

'progress_callback' is invoked repeatedly as the download
proceeds, if given, and is passed the downloader itself.

Returns True on success, False if cancelled.T)r?   )r   r2   rA   r   	COMPLETED)r,   Zprogress_callbackr@   r   joinZDownloader.joinm   s[     jjD,,,.  !$':::**zzT^^++r   c                s   \         P                  ! RV P                  4       V P                  V n        V P
                  '       d   V P
                  P                  4        V P                  '       d"   V P                  P                  4        RV n        \        P                  P                  V P                  4      '       d#   \        P                  ! V P                  4       R# R# )z2Request download stop and remove destination file.u   ❌ %sN)r   r1   r   r<   r   r   setr)   closer4   r5   r6   r	   r7   r.   r/   r   cancelZDownloader.cancel}   s    Xtxx(^^
!!###% $D77>>$))$$IIdii  %r   c                s    \         P                  P                  4       pR \        ,          VR&   V P                  '       d   V P                  VR&   V P
                  '       d(   V P
                  P                  4        F	  w  r#W1V&   K  	  \         P                  ! V P                  VR^V P                  R7      pVP                  ^8w  d-   \        P                  ! RV P                  VP                  4       VP                  4        \        VP
                  P                  RR4      P                  4       ;'       g    ^ 4      V n        V P"                  P%                  4        VP'                  RR	7       Fv  pV P(                  '       g    McV'       d>   V ;P*                  \-        V4      ,          un        V P(                  P/                  V4       V P"                  P%                  4        Kx  	  V P1                  4        R#   \2         d4   p\        P4                  ! R
T4       T P7                  T4        Rp?R# Rp?ii ; i)z	Lutris/%sz
User-AgentZRefererT)r   ZstreamZtimeoutr   z%s returned a %s errorzContent-LengthZ i    )
chunk_sizezDownload failed: %sN)requestsZutilsZdefault_headersr   r   r   ZitemsZgetr   r   Zstatus_coder   ZinfoZraise_for_statusZintZstripr   r+   rD   Ziter_contentr)   r   lenZwriteon_download_completed	ExceptionZ	exceptionon_download_failed)r,   r   ZkeyZvalueZresponseZchunkZexs   &      r   r8   ZDownloader.async_download   s   	(nn446G$/+$=GL!|||%)\\	"|||"&,,"4"4"6JC#(CL #7||DHHgdTV`d`l`lmH##s*4dhh@T@TU%%' !1!1!5!56F!K!Q!Q!S!X!XWXYDN##%!..$.?(((((CJ6(%%++E2##'') @ &&( 	(2B7##B''	(s2   ?H   H  #CH  <AH  A+H   H>(H99H>c                    < V ^8  d   QhRS[ /# )r   r   )rK   r   r   r   r   r      s     % %	 %r   c                s    V P                   V P                  8w  d   V P                  V n         Wn        V P                  '       d$   V P                  P                  4        R V n        R # R # N)r   r<   r=   r   r)   rE   )r,   r   r@   r   rL   ZDownloader.on_download_failed   sO     ::'DJJ##% $D r   c                sv   V P                   V P                  8X  d   R # \        P                  ! RV P                  4       V P
                  '       g   \        P                  ! R4       V P                  '       g   RV n        ^dV n	        V P                  V n         V P                  P                  4        R V n        R # )NzFinished downloading %szDownloaded file is emptyr;   )r   r<   r   r1   r   r   Zwarningr   r    r!   rB   r)   rE   r.   r/   r   rJ   Z Downloader.on_download_completed   s    ::'.9###NN56~~~%(D"'*D$^^
! r   c                sZ   V P                  4       V n        V P                  4       V n        \	        4       V n        V P                  V n        V P                  '       dO   \        V P                  4      \        V P                  4      ,          V n
        V P                  ^d,          V n        R# R# )z#Calculate and store download stats.N)	get_speedr"   get_average_time_leftr#   r3   r%   r   r$   r   Zfloatr    r!   r.   r/   r   r>   ZDownloader.get_stats   sz    !^^-335'z-->>>%*4+?+?%@5CX%XD"'+'='='CD$ r   c                s   \        4       V P                  ,
          pV^ 8  dQ   V P                  V P                  ,
          pW!,          ;'       g    ^p\        P
                  ! V P                  V4       V P                  '       g   V P                  # \        4       V P                  ,
          ^8  d   V P                  # \        V P                  4      ^8  d   V P                  P                  ^ 4       K7  \        V P                  4      ^8  d   V P                  ^R pMV P                  R,          p\        V4      \        V4      ,          p\        4       V n        V# )z0Return the average speed of the download so far.:NNNi)r3   r%   r   r$   bisectZinsortr&   r"   r'   rI   ZpopZsum)r,   elapsed_timerG   ZspeedZsamplesr"      &     r   rO   ZDownloader.get_speed   s   zD$8$88!-->J-22E MM$**E2 %%%:---1%%%$""#b(  #t 1$&&q,G&&q)GGs7|3 (
r   c                rM   )r   r   )r   r   r   r   r   r      s     : :s :r   c                sN   V P                   '       g   R# \        4       V P                  ,
          pV^8  d   V P                  # V P                   V P                  ,
          V P
                  ,          p\        V^<4      w  r4\        V^<4      w  rS\        4       V n        RWSV3,          # )z,Return average download time left as string.z???z%d:%02d:%02d)r   r3   r(   r#   r   r"   Zdivmod)r,   rR   Zaverage_time_leftZminutesZsecondsZhoursrS   r   rP   Z Downloader.get_average_time_left   s    ~~~zD$=$==!>>!!^^d.B.BBdFXFXX!"3R8,$,J! 999r   )r"   r   r	   r   r   r)   r   r   r%   r$   r&   r
   r+   r    r!   r   r'   r   r   r   r#   r(   r   )FNNN)FrN   )Z__name__Z
__module__Z__qualname__Z__firstlineno__Z__doc__ZlistZranger   r2   r<   r=   rB   r-   r0   r9   r:   rA   rC   rF   r8   rL   rJ   r>   rO   rP   Z__static_attributes__Z__classdictcell__)r   s   @r   r   r      sv      8<E!H~4T;	5)!0 !0F.	5!"&, 
!(6% %!	D>: :r   r   )rQ   r4   r*   ZtimeZtypingr    r   r   rH   Zlutrisr   Zlutris.utilr   Zlutris.util.logr   Z	monotonicr3   r   ) r   r   <module>rT      s:     	   & &    " >>`: `:r   