@@ -670,6 +670,54 @@ def get_download_target(url, dstpath, filename_prefix=''):
670
670
return file_name
671
671
672
672
673
+ def download_with_curl (url , file_name ):
674
+ print ("Downloading: %s from %s" % (file_name , url ))
675
+ if not which ('curl' ):
676
+ exit_with_error ('curl not found in PATH' )
677
+ # -#: show progress bar
678
+ # -L: Follow HTTP 3XX redirections
679
+ # -f: Fail on HTTP errors
680
+ subprocess .check_call (['curl' , '-#' , '-f' , '-L' , '-o' , file_name , url ])
681
+
682
+
683
+ def download_with_urllib (url , file_name ):
684
+ u = urlopen (url )
685
+ with open (file_name , 'wb' ) as f :
686
+ file_size = get_content_length (u )
687
+ if file_size > 0 :
688
+ print ("Downloading: %s from %s, %s Bytes" % (file_name , url , file_size ))
689
+ else :
690
+ print ("Downloading: %s from %s" % (file_name , url ))
691
+
692
+ file_size_dl = 0
693
+ # Draw a progress bar 80 chars wide (in non-TTY mode)
694
+ progress_max = 80 - 4
695
+ progress_shown = 0
696
+ block_sz = 256 * 1024
697
+ if not TTY_OUTPUT :
698
+ print (' [' , end = '' )
699
+ while True :
700
+ buffer = u .read (block_sz )
701
+ if not buffer :
702
+ break
703
+
704
+ file_size_dl += len (buffer )
705
+ f .write (buffer )
706
+ if file_size :
707
+ percent = file_size_dl * 100.0 / file_size
708
+ if TTY_OUTPUT :
709
+ status = r" %10d [%3.02f%%]" % (file_size_dl , percent )
710
+ print (status , end = '\r ' )
711
+ else :
712
+ while progress_shown < progress_max * percent / 100 :
713
+ print ('-' , end = '' )
714
+ sys .stdout .flush ()
715
+ progress_shown += 1
716
+ if not TTY_OUTPUT :
717
+ print (']' )
718
+ sys .stdout .flush ()
719
+
720
+
673
721
# On success, returns the filename on the disk pointing to the destination file that was produced
674
722
# On failure, returns None.
675
723
def download_file (url , dstpath , download_even_if_exists = False ,
@@ -680,53 +728,25 @@ def download_file(url, dstpath, download_even_if_exists=False,
680
728
if os .path .exists (file_name ) and not download_even_if_exists :
681
729
print ("File '" + file_name + "' already downloaded, skipping." )
682
730
return file_name
731
+
732
+ mkdir_p (os .path .dirname (file_name ))
733
+
683
734
try :
684
- u = urlopen (url )
685
- mkdir_p (os .path .dirname (file_name ))
686
- with open (file_name , 'wb' ) as f :
687
- file_size = get_content_length (u )
688
- if file_size > 0 :
689
- print ("Downloading: %s from %s, %s Bytes" % (file_name , url , file_size ))
690
- else :
691
- print ("Downloading: %s from %s" % (file_name , url ))
692
-
693
- file_size_dl = 0
694
- # Draw a progress bar 80 chars wide (in non-TTY mode)
695
- progress_max = 80 - 4
696
- progress_shown = 0
697
- block_sz = 256 * 1024
698
- if not TTY_OUTPUT :
699
- print (' [' , end = '' )
700
- while True :
701
- buffer = u .read (block_sz )
702
- if not buffer :
703
- break
704
-
705
- file_size_dl += len (buffer )
706
- f .write (buffer )
707
- if file_size :
708
- percent = file_size_dl * 100.0 / file_size
709
- if TTY_OUTPUT :
710
- status = r" %10d [%3.02f%%]" % (file_size_dl , percent )
711
- print (status , end = '\r ' )
712
- else :
713
- while progress_shown < progress_max * percent / 100 :
714
- print ('-' , end = '' )
715
- sys .stdout .flush ()
716
- progress_shown += 1
717
- if not TTY_OUTPUT :
718
- print (']' )
719
- sys .stdout .flush ()
735
+ # Use curl on macOS to avoid CERTIFICATE_VERIFY_FAILED issue with
736
+ # python's urllib:
737
+ # https://stackoverflow.com/questions/40684543/how-to-make-python-use-ca-certificates-from-mac-os-truststore
738
+ # Unlike on linux or windows, curl is always available on macOS systems.
739
+ if MACOS :
740
+ download_with_curl (url , file_name )
741
+ else :
742
+ download_with_urllib (url , file_name )
720
743
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 )
744
+ errlog ("Error: Downloading URL '" + url + "': " + str (e ))
726
745
return None
727
746
except KeyboardInterrupt :
728
747
rmfile (file_name )
729
- exit_with_error ("aborted by user, exiting" )
748
+ raise
749
+
730
750
return file_name
731
751
732
752
@@ -3093,4 +3113,8 @@ def print_tools(t):
3093
3113
3094
3114
3095
3115
if __name__ == '__main__' :
3096
- sys .exit (main (sys .argv [1 :]))
3116
+ try :
3117
+ sys .exit (main (sys .argv [1 :]))
3118
+ except KeyboardInterrupt :
3119
+ exit_with_error ('aborted by user, exiting' )
3120
+ sys .exit (1 )
0 commit comments