1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#!/usr/bin/env python
# Moved some utilities here from ../../configure
from __future__ import print_function
import hashlib
import sys
import zipfile
import tarfile
import contextlib
from urllib.request import build_opener, install_opener, urlretrieve
def formatSize(amt):
"""Format a size as a string in MB"""
return "%.1f" % (amt / 1024000.)
def spin(c):
"""print out an ASCII 'spinner' based on the value of counter 'c'"""
spin = ".:|'"
return (spin[c % len(spin)])
def reporthook(count, size, total):
"""internal hook used by retrievefile"""
sys.stdout.write(' Fetch: %c %sMB total, %sMB downloaded \r' %
(spin(count),
formatSize(total),
formatSize(count*size)))
def retrievefile(url, targetfile):
"""fetch file 'url' as 'targetfile'. Return targetfile or throw."""
try:
sys.stdout.write(' <%s>\nConnecting...\r' % url)
sys.stdout.flush()
opener = build_opener()
opener.addheaders = [('User-agent', f'Python-urllib/{sys.version_info.major}.{sys.version_info.minor} node.js/configure')]
install_opener(opener)
urlretrieve(url, targetfile, reporthook=reporthook)
print('') # clear the line
return targetfile
except IOError as err:
print(' ** IOError %s\n' % err)
return None
except:
print(' ** Error occurred while downloading\n <%s>' % url)
raise
def findHash(dict):
"""Find an available hash type."""
# choose from one of these
availAlgos = hashlib.algorithms_guaranteed
for hashAlgo in availAlgos:
if hashAlgo in dict:
return (dict[hashAlgo], hashAlgo, availAlgos)
# error
return (None, None, availAlgos)
def checkHash(targetfile, hashAlgo):
"""Check a file using hashAlgo. Return the hex digest."""
digest = hashlib.new(hashAlgo)
with open(targetfile, 'rb') as f:
chunk = f.read(1024)
while len(chunk) > 0:
digest.update(chunk)
chunk = f.read(1024)
return digest.hexdigest()
def unpack(packedfile, parent_path):
"""Unpacks packedfile into parent_path. Assumes .zip. Returns parent_path"""
if zipfile.is_zipfile(packedfile):
with contextlib.closing(zipfile.ZipFile(packedfile, 'r')) as icuzip:
print(' Extracting zipfile: %s' % packedfile)
icuzip.extractall(parent_path)
return parent_path
elif tarfile.is_tarfile(packedfile):
with contextlib.closing(tarfile.TarFile.open(packedfile, 'r')) as icuzip:
print(' Extracting tarfile: %s' % packedfile)
icuzip.extractall(parent_path)
return parent_path
else:
packedsuffix = packedfile.lower().split('.')[-1] # .zip, .tgz etc
raise Exception('Error: Don\'t know how to unpack %s with extension %s' % (packedfile, packedsuffix))
# List of possible "--download=" types.
download_types = set(['icu'])
# Default options for --download.
download_default = "none"
def help():
"""This function calculates the '--help' text for '--download'."""
return """Select which packages may be auto-downloaded.
valid values are: none, all, %s. (default is "%s").""" % (", ".join(download_types), download_default)
def set2dict(keys, value=None):
"""Convert some keys (iterable) to a dict."""
return dict((key, value) for (key) in keys)
def parse(opt):
"""This function parses the options to --download and returns a set such as { icu: true }, etc. """
if not opt:
opt = download_default
theOpts = set(opt.split(','))
if 'all' in theOpts:
# all on
return set2dict(download_types, True)
elif 'none' in theOpts:
# all off
return set2dict(download_types, False)
# OK. Now, process each of the opts.
theRet = set2dict(download_types, False)
for anOpt in opt.split(','):
if not anOpt or anOpt == "":
# ignore stray commas, etc.
continue
elif anOpt == 'all':
# all on
theRet = dict((key, True) for (key) in download_types)
else:
# turn this one on
if anOpt in download_types:
theRet[anOpt] = True
else:
# future proof: ignore unknown types
print('Warning: ignoring unknown --download= type "%s"' % anOpt)
# all done
return theRet
def candownload(auto_downloads, package):
if not (package in auto_downloads.keys()):
raise Exception('Internal error: "%s" is not in the --downloads list. Check nodedownload.py' % package)
if auto_downloads[package]:
return True
else:
print("""Warning: Not downloading package "%s". You could pass "--download=all"
(Windows: "download-all") to try auto-downloading it.""" % package)
return False
|