2121class Response :
2222 def __init__ (self , raw :bytes ):
2323 header_body = raw .split (b"\r \n \r \n " )
24+
25+ self .body = b""
2426
2527 if len (header_body ) == 1 :
2628 self .raw_header = header_body [0 ]
@@ -102,6 +104,10 @@ def run(self):
102104 data = self .connection .recv (MAX_SOCKET_CHUNK_SIZE )
103105 res = Response (data )
104106
107+ if res .body :
108+ self .file .write (res .body )
109+ self .init_data ["bytes_recv" ] += len (res .body )
110+
105111 while True :
106112 data = self .connection .recv (MAX_SOCKET_CHUNK_SIZE )
107113 if not data :
@@ -134,35 +140,51 @@ def __init__(self, init_data:dict):
134140
135141 self .time_interval = 0.10
136142
143+ self ._block_len = 0
144+ self ._last_bytes = 0
145+
146+ self .processbar = self .init_data .get ("processbar" )
147+
137148 def run (self ):
138149 block_len = 0
139150 last_bytes = 0
140- while self .len != block_len :
141- print ("\r " , end = "" )
142- block_len = (self .init_data ["bytes_recv" ]* self .len )// self .init_data ["length" ]
143- download_bytes_in_second = ((self .init_data ["bytes_recv" ]- last_bytes ) * (1 // self .time_interval ))
144- eta = f"{ self .init_data ['length' ]// download_bytes_in_second } s"
151+ while self .len != self ._block_len :
152+
153+ self ._block_len = (self .init_data ["bytes_recv" ]* self .len )// self .init_data ["length" ]
145154
146- eta_str = f" { next (self .loading )} ETA { eta :<20} "
147- download_bytes_in_second_str = f"{ download_bytes_in_second } bytes/second"
148- percentage = f" { next (self .loading )} [{ block_len * (100 // self .len )} /100]"
155+ download_bytes_in_second = ((self .init_data ["bytes_recv" ]- self ._last_bytes ) * (1 // self .time_interval ))
156+ self .download_bytes_in_second = download_bytes_in_second if download_bytes_in_second else 1
157+ self .download_bytes_in_second_str = f"{ download_bytes_in_second } bytes/second"
158+
159+ self .eta = f"{ self .init_data ['length' ]// self .download_bytes_in_second } s"
160+ self .eta_str = f" { next (self .loading )} ETA { self .eta :<20} "
149161
150- print ("downloading " + self .prefix + self .block * block_len + self .empty_space * (self .len - block_len ) + self .suffix + percentage , end = "" )
162+ self .percentage = self ._block_len * (100 // self .len )
163+
164+ animated_suff = f" { next (self .loading )} [{ self .percentage } /100]"
165+
166+ if self .processbar :
167+ print ("\r " , end = "" )
168+ print ("downloading " + self .prefix + self .block * self ._block_len + self .empty_space * (self .len - self ._block_len ) + self .suffix + animated_suff , end = "" )
151169
152170 last_bytes = self .init_data ["bytes_recv" ]
153171 time .sleep (self .time_interval )
154172
155- print ("" )
173+ if self .processbar :
174+ print ("" )
175+
156176
157177class Download :
158- def __init__ (self , url :str , connection :int = None , filename :str = None , headers :dict = dict ()):
178+ def __init__ (self , url :str , connection :int = None , filename :str = None , headers :dict = dict (), processbar : bool = True ):
159179 self .url = url
160180 self .url_obj = Url (self .url )
161181
162182 self .filename = filename
163183 self .connection = connection
184+ self .processbar = None
164185
165- self .data = dict (bytes_recv = 0 , url = self .url_obj , connection = connection , filename = filename )
186+ self .data = dict (bytes_recv = 0 , url = self .url_obj , connection = connection ,
187+ filename = filename , processbar = processbar )
166188
167189 self .master_payload = self .make_payload (headers = headers )
168190
@@ -181,7 +203,7 @@ def make_payload(self, bytes_range:list=None, headers:dict=None):
181203 for key , value in headers .items ():
182204 payload += f"{ key } : { value } \r \n "
183205
184- payload += "\r \n "
206+ payload += "\r \n "
185207
186208 return payload .encode ()
187209
@@ -224,7 +246,8 @@ def proces(self):
224246
225247 workers .append (w )
226248
227- ProcessBar (init_data = self .data ).start ()
249+ self .processbar = ProcessBar (init_data = self .data )
250+ self .processbar .start ()
228251
229252 [worker .join () for worker in workers ]
230253
@@ -254,9 +277,11 @@ def get_filename(self, response:object):
254277 def get_range (self , length :int , connection :int ):
255278 steps = length // connection
256279 ranges = []
257- for n in range (0 , length , steps ):
258- ranges .append ([n , n + steps - 1 ])
259-
280+ for n in range (connection ):
281+ if connection == (n + 1 ):
282+ ranges .append ([n * steps , length ])
283+ continue
284+ ranges .append ([n * steps , (n * steps )+ steps - 1 ])
260285 return ranges
261286
262287 def predict_conn (self , response :object ):
@@ -282,7 +307,7 @@ def predict_conn(self, response:object):
282307
283308
284309if __name__ == '__main__' :
285- link = "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-x86_64"
310+ link = input ( "Enter url -->" )
286311 down = Download (url = link )
287312 down .proces ()
288313
0 commit comments