|
1 | | -#!/usr/local/bin/python |
| 1 | +#!/usr/bin/env python3 |
2 | 2 | # |
3 | 3 | # Copyright Contributors to the OpenVDB Project |
4 | 4 | # SPDX-License-Identifier: MPL-2.0 |
|
19 | 19 | import requests |
20 | 20 | import hashlib |
21 | 21 | import os |
| 22 | +import argparse |
| 23 | +import copy |
22 | 24 |
|
23 | | -# this argument is for the major.minor version of Houdini to download (such as 15.0, 15.5, 16.0) |
24 | | -version = sys.argv[1] |
25 | | -only_production = True if sys.argv[2] == 'ON' else False |
26 | | -user_client_id = os.getenv('HOUDINI_CLIENT_ID') |
27 | | -user_client_secret_key = os.getenv('HOUDINI_SECRET_KEY') |
28 | | - |
29 | | -if not re.match('[0-9][0-9]\.[0-9]$', version): |
30 | | - raise IOError('Invalid Houdini Version "%s", expecting in the form "major.minor" such as "16.0"' % version) |
31 | | - |
| 25 | +# For progress bar printing |
| 26 | +try: |
| 27 | + from tqdm import tqdm |
| 28 | + has_tqdm = True |
| 29 | +except: |
| 30 | + has_tqdm = False |
| 31 | + pass |
32 | 32 |
|
33 | 33 | # Code that provides convenient Python wrappers to call into the API: |
34 | 34 |
|
@@ -138,33 +138,72 @@ def __init__(self, http_code, message): |
138 | 138 | self.http_code = http_code |
139 | 139 |
|
140 | 140 |
|
141 | | -service = service( |
142 | | - access_token_url="https://www.sidefx.com/oauth2/application_token", |
143 | | - client_id=user_client_id, |
144 | | - client_secret_key=user_client_secret_key, |
145 | | - endpoint_url="https://www.sidefx.com/api/", |
146 | | - ) |
| 141 | +if __name__ == "__main__": |
| 142 | + |
| 143 | + parser = argparse.ArgumentParser(description='Download a Houdini Installation') |
| 144 | + parser.add_argument('version', type=str, help='Major.Minor version of Houdini to download') |
| 145 | + parser.add_argument('platform', type=str, help='Platform target') |
| 146 | + parser.add_argument('--prod', action='store_true', help='Only download production builds') |
| 147 | + parser.add_argument('--list', action='store_true', help='Just list the available builds and exit.') |
| 148 | + args = parser.parse_args() |
| 149 | + |
| 150 | + version = args.version |
| 151 | + platform = args.platform |
| 152 | + only_production = args.prod |
| 153 | + |
| 154 | + user_client_id = os.getenv('HOUDINI_CLIENT_ID') |
| 155 | + user_client_secret_key = os.getenv('HOUDINI_SECRET_KEY') |
| 156 | + |
| 157 | + if not re.match('[0-9][0-9]\.[0-9]$', version): |
| 158 | + raise IOError('Invalid Houdini Version "%s", expecting in the form "major.minor" such as "16.0"' % version) |
147 | 159 |
|
148 | | -releases_list = service.download.get_daily_builds_list( |
149 | | - product='houdini', version=version, platform='linux', only_production=only_production) |
| 160 | + service = service( |
| 161 | + access_token_url="https://www.sidefx.com/oauth2/application_token", |
| 162 | + client_id=user_client_id, |
| 163 | + client_secret_key=user_client_secret_key, |
| 164 | + endpoint_url="https://www.sidefx.com/api/", |
| 165 | + ) |
150 | 166 |
|
151 | | -latest_release = service.download.get_daily_build_download( |
152 | | - product='houdini', version=version, platform='linux', build=releases_list[0]['build']) |
| 167 | + releases_list = service.download.get_daily_builds_list( |
| 168 | + product='houdini', version=version, platform=platform, only_production=only_production) |
153 | 169 |
|
154 | | -# Download the file as hou.tar.gz |
155 | | -local_filename = 'hou.tar.gz' |
156 | | -response = requests.get(latest_release['download_url'], stream=True) |
157 | | -if response.status_code == 200: |
158 | | - with open(local_filename, 'wb') as f: |
| 170 | + print('Available builds:') |
| 171 | + for rel in releases_list: |
| 172 | + rel = copy.deepcopy(rel) |
| 173 | + if 'third_party_libraries' in rel: |
| 174 | + # Don't print these |
| 175 | + del rel['third_party_libraries'] |
| 176 | + print(rel) |
| 177 | + |
| 178 | + if args.list: |
| 179 | + sys.exit(0) |
| 180 | + |
| 181 | + print('Selecting build: ' + releases_list[0]['build']) |
| 182 | + |
| 183 | + latest_release = service.download.get_daily_build_download( |
| 184 | + product='houdini', version=version, platform=platform, build=releases_list[0]['build']) |
| 185 | + |
| 186 | + # Download the file as hou.tar.gz |
| 187 | + local_filename = 'hou.tar.gz' |
| 188 | + response = requests.get(latest_release['download_url'], stream=True) |
| 189 | + if response.status_code == 200: |
159 | 190 | response.raw.decode_content = True |
160 | | - shutil.copyfileobj(response.raw, f) |
161 | | -else: |
162 | | - raise Exception('Error downloading file!') |
163 | | - |
164 | | -# Verify the file checksum is matching |
165 | | -file_hash = hashlib.md5() |
166 | | -with open(local_filename, 'rb') as f: |
167 | | - for chunk in iter(lambda: f.read(4096), b''): |
168 | | - file_hash.update(chunk) |
169 | | -if file_hash.hexdigest() != latest_release['hash']: |
170 | | - raise Exception('Checksum does not match!') |
| 191 | + if has_tqdm: |
| 192 | + file_size = int(response.headers.get('Content-Length', 0)) |
| 193 | + desc = "(Unknown total file size)" if file_size == 0 else "" |
| 194 | + with tqdm.wrapattr(response.raw, "read", total=file_size, desc=desc) as r_raw: |
| 195 | + with open(local_filename, 'wb') as f: |
| 196 | + shutil.copyfileobj(r_raw, f) |
| 197 | + else: |
| 198 | + with open(local_filename, 'wb') as f: |
| 199 | + shutil.copyfileobj(response.raw, f) |
| 200 | + else: |
| 201 | + raise Exception('Error downloading file!') |
| 202 | + |
| 203 | + # Verify the file checksum is matching |
| 204 | + file_hash = hashlib.md5() |
| 205 | + with open(local_filename, 'rb') as f: |
| 206 | + for chunk in iter(lambda: f.read(4096), b''): |
| 207 | + file_hash.update(chunk) |
| 208 | + if file_hash.hexdigest() != latest_release['hash']: |
| 209 | + raise Exception('Checksum does not match!') |
0 commit comments