@@ -670,19 +670,19 @@ def get_download_target(url, dstpath, filename_prefix=''):
670670 return file_name
671671
672672
673- # On success, returns the filename on the disk pointing to the destination file that was produced
674- # On failure, returns None.
675- def download_file (url , dstpath , download_even_if_exists = False ,
676- filename_prefix = '' , silent = False ):
677- debug_print ('download_file(url=' + url + ', dstpath=' + dstpath + ')' )
678- file_name = get_download_target (url , dstpath , filename_prefix )
673+ def download_with_curl (url , file_name ):
674+ # -#: show progress bar
675+ # -L: Follow HTTP 3XX redirections
676+ # -f: Fail on HTTP errors
677+ print ("Downloading: %s from %s" % (file_name , url ))
678+ if not which ('curl' ):
679+ exit_with_error ('curl not found in PATH' )
680+ subprocess .check_call (['curl' , '-#' , '-f' , '-L' , '-o' , file_name , url ])
679681
680- if os .path .exists (file_name ) and not download_even_if_exists :
681- print ("File '" + file_name + "' already downloaded, skipping." )
682- return file_name
682+
683+ def download_with_urllib (url , file_name ):
683684 try :
684685 u = urlopen (url )
685- mkdir_p (os .path .dirname (file_name ))
686686 with open (file_name , 'wb' ) as f :
687687 file_size = get_content_length (u )
688688 if file_size > 0 :
@@ -717,16 +717,36 @@ def download_file(url, dstpath, download_even_if_exists=False,
717717 if not TTY_OUTPUT :
718718 print (']' )
719719 sys .stdout .flush ()
720- except Exception as e :
721- if not silent :
722- errlog ("Error: Downloading URL '" + url + "': " + str (e ))
723- if "SSL: CERTIFICATE_VERIFY_FAILED" in str (e ) or "urlopen error unknown url type: https" in str (e ):
724- errlog ("Warning: Possibly SSL/TLS issue. Update or install Python SSL root certificates (2048-bit or greater) supplied in Python folder or https://pypi.org/project/certifi/ and try again." )
725- rmfile (file_name )
726- return None
727720 except KeyboardInterrupt :
728721 rmfile (file_name )
729- exit_with_error ("aborted by user, exiting" )
722+
723+
724+ # On success, returns the filename on the disk pointing to the destination file that was produced
725+ # On failure, returns None.
726+ def download_file (url , dstpath , download_even_if_exists = False ,
727+ filename_prefix = '' , silent = False ):
728+ debug_print ('download_file(url=' + url + ', dstpath=' + dstpath + ')' )
729+ file_name = get_download_target (url , dstpath , filename_prefix )
730+
731+ if os .path .exists (file_name ) and not download_even_if_exists :
732+ print ("File '" + file_name + "' already downloaded, skipping." )
733+ return file_name
734+
735+ mkdir_p (os .path .dirname (file_name ))
736+
737+ try :
738+ # Use curl on macOS to avoid CERTIFICATE_VERIFY_FAILED issue with
739+ # python's urllib:
740+ # https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore
741+ # Unlike on linux or windows, curl is always available on macOS systems.
742+ if MACOS :
743+ download_with_curl (url , file_name )
744+ else :
745+ download_with_urllib (url , file_name )
746+ except Exception as e :
747+ errlog ("Error: Downloading URL '" + url + "': " + str (e ))
748+ return None
749+
730750 return file_name
731751
732752
@@ -3072,4 +3092,8 @@ def print_tools(t):
30723092
30733093
30743094if __name__ == '__main__' :
3075- sys .exit (main (sys .argv [1 :]))
3095+ try :
3096+ sys .exit (main (sys .argv [1 :]))
3097+ except KeyboardInterrupt :
3098+ exit_with_error ('aborted by user, exiting' )
3099+ sys .exit (1 )
0 commit comments