buildman: Move the download function to tools

This function is handy for binman as well. Move it into the shared 'tools'
module.

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/patman/tools.py b/tools/patman/tools.py
index 7af4a52..2f817f6 100644
--- a/tools/patman/tools.py
+++ b/tools/patman/tools.py
@@ -10,6 +10,7 @@
 import struct
 import sys
 import tempfile
+import urllib.request
 
 from patman import command
 from patman import tout
@@ -632,3 +633,47 @@
     if not pager:
         pager = ['more']
     command.Run(*pager, fname)
+
+def Download(url):
+    """Download a file to a temporary directory
+
+    Args:
+        url: URL to download
+    Returns:
+        Tuple:
+            Temporary directory name
+            Full path to the downloaded archive file in that directory,
+                or None if there was an error while downloading
+    """
+    print('Downloading: %s' % url)
+    leaf = url.split('/')[-1]
+    tmpdir = tempfile.mkdtemp('.buildman')
+    response = urllib.request.urlopen(url)
+    fname = os.path.join(tmpdir, leaf)
+    fd = open(fname, 'wb')
+    meta = response.info()
+    size = int(meta.get('Content-Length'))
+    done = 0
+    block_size = 1 << 16
+    status = ''
+
+    # Read the file in chunks and show progress as we go
+    while True:
+        buffer = response.read(block_size)
+        if not buffer:
+            print(chr(8) * (len(status) + 1), '\r', end=' ')
+            break
+
+        done += len(buffer)
+        fd.write(buffer)
+        status = r'%10d MiB  [%3d%%]' % (done // 1024 // 1024,
+                                            done * 100 // size)
+        status = status + chr(8) * (len(status) + 1)
+        print(status, end=' ')
+        sys.stdout.flush()
+    fd.close()
+    if done != size:
+        print('Error, failed to download')
+        os.remove(fname)
+        fname = None
+    return tmpdir, fname