SkQP: Stop requiring users to use posix shell

Also update README.md

Change-Id: I62f5ac38ff4a8c3aa19d895441a76664cb8e8176
Reviewed-on: https://skia-review.googlesource.com/99302
Reviewed-by: Hal Canary <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/tools/skqp/download_model b/tools/skqp/download_model
new file mode 100755
index 0000000..de1aeed
--- /dev/null
+++ b/tools/skqp/download_model
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+
+# Copyright 2018 Google Inc.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import hashlib
+import os
+import shutil
+import sys
+import threading
+import urllib2
+
+def checksum(path):
+    if not os.path.exists(path):
+        return None
+    m = hashlib.md5()
+    with open(path, 'rb') as f:
+        while True:
+            buf = f.read(4096)
+            if 0 == len(buf):
+                return m.hexdigest()
+            m.update(buf)
+
+def download(md5, path):
+    if not md5 == checksum(path):
+        dirname = os.path.dirname(path)
+        if dirname and not os.path.exists(dirname):
+            try:
+                os.makedirs(dirname)
+            except:
+                # ignore race condition
+                if not os.path.exists(dirname):
+                    raise
+        url = 'https://storage.googleapis.com/skia-skqp-assets/' + md5
+        with open(path, 'wb') as o:
+            shutil.copyfileobj(urllib2.urlopen(url), o)
+
+def main():
+    os.chdir(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
+                         'platform_tools', 'android', 'apps', 'skqp', 'src',
+                         'main', 'assets'))
+    sys.stderr.write('\n    0 / ????   ')
+    with open('files.checksum', 'r') as f:
+        md5 = f.read().strip()
+        assert(len(md5) == 32)
+        download(md5, 'files.txt')
+    with open('files.txt', 'r') as f:
+        records = []
+        for line in f:
+            md5, path = line.strip().split(';', 1)
+            records.append((md5, path))
+    threads = set()
+    sys.stderr.write('\r    0 / %d   ' % len(records))
+    for i, record in enumerate(records):
+        t = threading.Thread(target=download, args=record)
+        t.start()
+        threads.add(t)
+    left = -1
+    while left != 0:
+        count = sum(1 for t in threading.enumerate() if t in threads)
+        if left != count:
+            left = count
+            sys.stderr.write('\r %4d / %d   ' % (len(records) - left, len(records)))
+    sys.stderr.write('\n')
+
+if __name__ == '__main__':
+    main()