summaryrefslogtreecommitdiff
path: root/tools/configure.d/nodedownload.py
blob: e3fe2c517cc1bb275b1564f643d861ae3833b0a9 (plain)
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
#!/usr/bin/env python
# Moved some utilities here from ../../configure

from __future__ import print_function
import urllib
import hashlib
import sys
import zipfile
import tarfile
import fpformat
import contextlib

def formatSize(amt):
    """Format a size as a string in MB"""
    return fpformat.fix(amt / 1024000., 1)

def spin(c):
    """print out an ASCII 'spinner' based on the value of counter 'c'"""
    spin = ".:|'"
    return (spin[c % len(spin)])

class ConfigOpener(urllib.FancyURLopener):
    """fancy opener used by retrievefile. Set a UA"""
    # append to existing version (UA)
    version = '%s node.js/configure' % urllib.URLopener.version

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()
        ConfigOpener().retrieve(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 md5sum(targetfile):
    """md5sum a file. Return the hex digest."""
    digest = hashlib.md5()
    with open(targetfile, 'rb') as f:
      chunk = f.read(1024)
      while chunk !=  "":
        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 is '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