11cb0ef41Sopenharmony_ci#!/usr/bin/env python 21cb0ef41Sopenharmony_ci# Moved some utilities here from ../../configure 31cb0ef41Sopenharmony_ci 41cb0ef41Sopenharmony_cifrom __future__ import print_function 51cb0ef41Sopenharmony_ciimport hashlib 61cb0ef41Sopenharmony_ciimport sys 71cb0ef41Sopenharmony_ciimport zipfile 81cb0ef41Sopenharmony_ciimport tarfile 91cb0ef41Sopenharmony_ciimport contextlib 101cb0ef41Sopenharmony_citry: 111cb0ef41Sopenharmony_ci from urllib.request import FancyURLopener, URLopener 121cb0ef41Sopenharmony_ciexcept ImportError: 131cb0ef41Sopenharmony_ci from urllib import FancyURLopener, URLopener 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cidef formatSize(amt): 161cb0ef41Sopenharmony_ci """Format a size as a string in MB""" 171cb0ef41Sopenharmony_ci return "%.1f" % (amt / 1024000.) 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_cidef spin(c): 201cb0ef41Sopenharmony_ci """print out an ASCII 'spinner' based on the value of counter 'c'""" 211cb0ef41Sopenharmony_ci spin = ".:|'" 221cb0ef41Sopenharmony_ci return (spin[c % len(spin)]) 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ciclass ConfigOpener(FancyURLopener): 251cb0ef41Sopenharmony_ci """fancy opener used by retrievefile. Set a UA""" 261cb0ef41Sopenharmony_ci # append to existing version (UA) 271cb0ef41Sopenharmony_ci version = '%s node.js/configure' % URLopener.version 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_cidef reporthook(count, size, total): 301cb0ef41Sopenharmony_ci """internal hook used by retrievefile""" 311cb0ef41Sopenharmony_ci sys.stdout.write(' Fetch: %c %sMB total, %sMB downloaded \r' % 321cb0ef41Sopenharmony_ci (spin(count), 331cb0ef41Sopenharmony_ci formatSize(total), 341cb0ef41Sopenharmony_ci formatSize(count*size))) 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cidef retrievefile(url, targetfile): 371cb0ef41Sopenharmony_ci """fetch file 'url' as 'targetfile'. Return targetfile or throw.""" 381cb0ef41Sopenharmony_ci try: 391cb0ef41Sopenharmony_ci sys.stdout.write(' <%s>\nConnecting...\r' % url) 401cb0ef41Sopenharmony_ci sys.stdout.flush() 411cb0ef41Sopenharmony_ci ConfigOpener().retrieve(url, targetfile, reporthook=reporthook) 421cb0ef41Sopenharmony_ci print('') # clear the line 431cb0ef41Sopenharmony_ci return targetfile 441cb0ef41Sopenharmony_ci except IOError as err: 451cb0ef41Sopenharmony_ci print(' ** IOError %s\n' % err) 461cb0ef41Sopenharmony_ci return None 471cb0ef41Sopenharmony_ci except: 481cb0ef41Sopenharmony_ci print(' ** Error occurred while downloading\n <%s>' % url) 491cb0ef41Sopenharmony_ci raise 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_cidef findHash(dict): 521cb0ef41Sopenharmony_ci """Find an available hash type.""" 531cb0ef41Sopenharmony_ci # choose from one of these 541cb0ef41Sopenharmony_ci availAlgos = hashlib.algorithms_guaranteed 551cb0ef41Sopenharmony_ci for hashAlgo in availAlgos: 561cb0ef41Sopenharmony_ci if hashAlgo in dict: 571cb0ef41Sopenharmony_ci return (dict[hashAlgo], hashAlgo, availAlgos) 581cb0ef41Sopenharmony_ci # error 591cb0ef41Sopenharmony_ci return (None, None, availAlgos) 601cb0ef41Sopenharmony_ci 611cb0ef41Sopenharmony_cidef checkHash(targetfile, hashAlgo): 621cb0ef41Sopenharmony_ci """Check a file using hashAlgo. Return the hex digest.""" 631cb0ef41Sopenharmony_ci digest = hashlib.new(hashAlgo) 641cb0ef41Sopenharmony_ci with open(targetfile, 'rb') as f: 651cb0ef41Sopenharmony_ci chunk = f.read(1024) 661cb0ef41Sopenharmony_ci while len(chunk) > 0: 671cb0ef41Sopenharmony_ci digest.update(chunk) 681cb0ef41Sopenharmony_ci chunk = f.read(1024) 691cb0ef41Sopenharmony_ci return digest.hexdigest() 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_cidef unpack(packedfile, parent_path): 721cb0ef41Sopenharmony_ci """Unpacks packedfile into parent_path. Assumes .zip. Returns parent_path""" 731cb0ef41Sopenharmony_ci if zipfile.is_zipfile(packedfile): 741cb0ef41Sopenharmony_ci with contextlib.closing(zipfile.ZipFile(packedfile, 'r')) as icuzip: 751cb0ef41Sopenharmony_ci print(' Extracting zipfile: %s' % packedfile) 761cb0ef41Sopenharmony_ci icuzip.extractall(parent_path) 771cb0ef41Sopenharmony_ci return parent_path 781cb0ef41Sopenharmony_ci elif tarfile.is_tarfile(packedfile): 791cb0ef41Sopenharmony_ci with contextlib.closing(tarfile.TarFile.open(packedfile, 'r')) as icuzip: 801cb0ef41Sopenharmony_ci print(' Extracting tarfile: %s' % packedfile) 811cb0ef41Sopenharmony_ci icuzip.extractall(parent_path) 821cb0ef41Sopenharmony_ci return parent_path 831cb0ef41Sopenharmony_ci else: 841cb0ef41Sopenharmony_ci packedsuffix = packedfile.lower().split('.')[-1] # .zip, .tgz etc 851cb0ef41Sopenharmony_ci raise Exception('Error: Don\'t know how to unpack %s with extension %s' % (packedfile, packedsuffix)) 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci# List of possible "--download=" types. 881cb0ef41Sopenharmony_cidownload_types = set(['icu']) 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci# Default options for --download. 911cb0ef41Sopenharmony_cidownload_default = "none" 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_cidef help(): 941cb0ef41Sopenharmony_ci """This function calculates the '--help' text for '--download'.""" 951cb0ef41Sopenharmony_ci return """Select which packages may be auto-downloaded. 961cb0ef41Sopenharmony_civalid values are: none, all, %s. (default is "%s").""" % (", ".join(download_types), download_default) 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_cidef set2dict(keys, value=None): 991cb0ef41Sopenharmony_ci """Convert some keys (iterable) to a dict.""" 1001cb0ef41Sopenharmony_ci return dict((key, value) for (key) in keys) 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_cidef parse(opt): 1031cb0ef41Sopenharmony_ci """This function parses the options to --download and returns a set such as { icu: true }, etc. """ 1041cb0ef41Sopenharmony_ci if not opt: 1051cb0ef41Sopenharmony_ci opt = download_default 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci theOpts = set(opt.split(',')) 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci if 'all' in theOpts: 1101cb0ef41Sopenharmony_ci # all on 1111cb0ef41Sopenharmony_ci return set2dict(download_types, True) 1121cb0ef41Sopenharmony_ci elif 'none' in theOpts: 1131cb0ef41Sopenharmony_ci # all off 1141cb0ef41Sopenharmony_ci return set2dict(download_types, False) 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci # OK. Now, process each of the opts. 1171cb0ef41Sopenharmony_ci theRet = set2dict(download_types, False) 1181cb0ef41Sopenharmony_ci for anOpt in opt.split(','): 1191cb0ef41Sopenharmony_ci if not anOpt or anOpt == "": 1201cb0ef41Sopenharmony_ci # ignore stray commas, etc. 1211cb0ef41Sopenharmony_ci continue 1221cb0ef41Sopenharmony_ci elif anOpt == 'all': 1231cb0ef41Sopenharmony_ci # all on 1241cb0ef41Sopenharmony_ci theRet = dict((key, True) for (key) in download_types) 1251cb0ef41Sopenharmony_ci else: 1261cb0ef41Sopenharmony_ci # turn this one on 1271cb0ef41Sopenharmony_ci if anOpt in download_types: 1281cb0ef41Sopenharmony_ci theRet[anOpt] = True 1291cb0ef41Sopenharmony_ci else: 1301cb0ef41Sopenharmony_ci # future proof: ignore unknown types 1311cb0ef41Sopenharmony_ci print('Warning: ignoring unknown --download= type "%s"' % anOpt) 1321cb0ef41Sopenharmony_ci # all done 1331cb0ef41Sopenharmony_ci return theRet 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_cidef candownload(auto_downloads, package): 1361cb0ef41Sopenharmony_ci if not (package in auto_downloads.keys()): 1371cb0ef41Sopenharmony_ci raise Exception('Internal error: "%s" is not in the --downloads list. Check nodedownload.py' % package) 1381cb0ef41Sopenharmony_ci if auto_downloads[package]: 1391cb0ef41Sopenharmony_ci return True 1401cb0ef41Sopenharmony_ci else: 1411cb0ef41Sopenharmony_ci print("""Warning: Not downloading package "%s". You could pass "--download=all" 1421cb0ef41Sopenharmony_ci (Windows: "download-all") to try auto-downloading it.""" % package) 1431cb0ef41Sopenharmony_ci return False 144