@@ -113,17 +113,12 @@ def http_head(url):
113113 return exc .getcode ()
114114
115115
116- def http_download (url , message = None , checksum = None , hash_alg = 'sha1' , dl_size = None , background = False ): # pylint: disable=too-many-statements
116+ # pylint: disable=too-many-positional-arguments
117+ def http_download (url , message = None , checksum = None , hash_alg = 'sha1' , dl_size = None , background = False ):
117118 """Makes HTTP request and displays a progress dialog on download."""
118- if checksum :
119- from hashlib import md5 , sha1
120- if hash_alg == 'sha1' :
121- calc_checksum = sha1 ()
122- elif hash_alg == 'md5' :
123- calc_checksum = md5 ()
124- else :
125- log (4 , 'Invalid hash algorithm specified: {}' .format (hash_alg ))
126- checksum = None
119+ calc_checksum = _initialize_checksum (checksum , hash_alg )
120+ if checksum and not calc_checksum :
121+ checksum = None
127122
128123 response = _http_request (url )
129124 if response is None :
@@ -139,30 +134,66 @@ def http_download(url, message=None, checksum=None, hash_alg='sha1', dl_size=Non
139134 log (2 , 'The given file size does not match the request!' )
140135 dl_size = total_length
141136
142- if background :
143- progress = bg_progress_dialog ()
144- else :
145- progress = progress_dialog ()
137+ progress = _create_progress_dialog (background , message )
138+
139+ success = _download_file (response , dl_path , calc_checksum , total_length , message , progress , background )
140+
141+ progress .close ()
142+ response .close ()
143+
144+ if not success :
145+ return False
146+
147+ checksum_ok = _verify_checksum (checksum , calc_checksum )
148+ size_ok = _verify_size (dl_size , dl_path )
149+
150+ if not checksum_ok or not size_ok :
151+ if not _handle_corrupt_file (dl_size , dl_path , checksum , calc_checksum , filename ):
152+ return False
153+
154+ return dl_path
155+
156+
157+ def _initialize_checksum (checksum , hash_alg ):
158+ if not checksum :
159+ return None
160+
161+ from hashlib import md5 , sha1
162+ if hash_alg == 'sha1' :
163+ return sha1 ()
164+ if hash_alg == 'md5' :
165+ return md5 ()
166+ log (4 , 'Invalid hash algorithm specified: {}' .format (hash_alg ))
167+ return None
168+
169+
170+ def _create_progress_dialog (background , message ):
171+ progress = bg_progress_dialog () if background else progress_dialog ()
146172 progress .create (localize (30014 ), message = message ) # Download in progress
173+ return progress
174+
147175
176+ # pylint: disable=too-many-positional-arguments
177+ def _download_file (response , dl_path , calc_checksum , total_length , message , progress , background ):
148178 starttime = time ()
149179 chunk_size = 32 * 1024
150180 size = 0
181+
151182 with open (compat_path (dl_path ), 'wb' ) as image :
152183 while True :
153184 chunk = response .read (chunk_size )
154185 if not chunk :
155186 break
156187
157188 image .write (chunk )
158- if checksum :
189+ if calc_checksum :
159190 calc_checksum .update (chunk )
160191 size += len (chunk )
161192 percent = int (round (size * 100 / total_length )) if total_length > 0 else 0
193+
162194 if not background and progress .iscanceled ():
163- progress .close ()
164- response .close ()
165195 return False
196+
166197 if time () - starttime > 5 and size > 0 :
167198 time_left = int (round ((total_length - size ) * (time () - starttime ) / size ))
168199 prog_message = '{line1}\n {line2}' .format (
@@ -173,25 +204,36 @@ def http_download(url, message=None, checksum=None, hash_alg='sha1', dl_size=Non
173204
174205 progress .update (percent , prog_message )
175206
176- progress .close ()
177- response .close ()
207+ return True
178208
179- checksum_ok = (not checksum or calc_checksum .hexdigest () == checksum )
180- size_ok = (not dl_size or stat_file (dl_path ).st_size () == dl_size )
181-
182- if not all ((checksum_ok , size_ok )):
183- log (4 , 'Something may be wrong with the downloaded file.' )
184- if not checksum_ok :
185- log (4 , 'Provided checksum: {}\n Calculated checksum: {}' .format (checksum , calc_checksum .hexdigest ()))
186- if not size_ok :
187- free_space = sizeof_fmt (diskspace ())
188- log (4 , 'Expected filesize: {}\n Real filesize: {}\n Remaining diskspace: {}' .format (dl_size , stat_file (dl_path ).st_size (), free_space ))
189- if yesno_dialog (localize (30003 ), localize (30070 , filename = filename )):
190- log (4 , 'Continuing despite possibly corrupt file!' )
191- else :
192- return False
193209
194- return dl_path
210+ def _verify_checksum (checksum , calc_checksum ):
211+ if not checksum :
212+ return True
213+ if calc_checksum :
214+ return calc_checksum .hexdigest () == checksum
215+ return False
216+
217+
218+ def _verify_size (dl_size , dl_path ):
219+ if not dl_size :
220+ return True
221+ return stat_file (dl_path ).st_size () == dl_size
222+
223+
224+ def _handle_corrupt_file (dl_size , dl_path , checksum , calc_checksum , filename ):
225+ log (4 , 'Something may be wrong with the downloaded file.' )
226+ if checksum and calc_checksum :
227+ log (4 , 'Provided checksum: {}\n Calculated checksum: {}' .format (checksum , calc_checksum .hexdigest ()))
228+ if dl_size :
229+ free_space = sizeof_fmt (diskspace ())
230+ log (4 , 'Expected filesize: {}\n Real filesize: {}\n Remaining diskspace: {}' .format (
231+ dl_size , stat_file (dl_path ).st_size (), free_space ))
232+ if yesno_dialog (localize (30003 ), localize (30070 , filename = filename )):
233+ log (4 , 'Continuing despite possibly corrupt file!' )
234+ return True
235+
236+ return False
195237
196238
197239def unzip (source , destination , file_to_unzip = None , result = []): # pylint: disable=dangerous-default-value
0 commit comments