123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- import os
- import time
- import math
- import signal
- import threading
- import xml.etree.ElementTree as ET
- from urllib3 import PoolManager
- from binascii import crc32
- def sigint_handler(num, frame):
- os._exit(0)
- signal.signal(signal.SIGINT, sigint_handler)
- def download(files, folder):
- global downloaded
- manager = PoolManager()
- for file in files:
- path = file.find('path').text
- length = int(file.find('length').text)
- checksum = int(file.find('checksum').text) % (1 << 32)
- file_name = os.path.join(local_path, folder, path.replace('\\', os.sep))
- dir_name = os.path.dirname(file_name)
- if not os.path.isdir(dir_name):
- os.makedirs(dir_name)
- while not os.path.isfile(file_name) or os.path.getsize(file_name) != length or (crc32(open(file_name, 'rb').read()) != checksum and checksum != 4294967295):
- open(file_name, 'wb').write(manager.request('GET', '%s%s/%s' % (base_url, folder, path.replace('\\', '/'))).data)
- downloaded += 1
- base_url = 'http://cdn.zwift.com/gameassets/Zwift_Updates_Root/'
- local_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'cdn', 'gameassets', 'Zwift_Updates_Root')
- for file in ['Zwift_ver_cur.xml', 'ZwiftMac_ver_cur.xml']:
- tree = ET.parse(os.path.join(local_path, file))
- root = tree.getroot()
- manifest = root.get('manifest')
- manifest_checksum = int(root.get('manifest_checksum')) % (1 << 32)
- manifest_file = os.path.join(local_path, manifest)
- while not os.path.isfile(manifest_file) or crc32(open(manifest_file, 'rb').read()) != manifest_checksum:
- open(manifest_file, 'wb').write(PoolManager().request('GET', base_url + manifest).data)
- tree = ET.parse(manifest_file)
- root = tree.getroot()
- folder = root.get('folder')
- all_files = list(root.iter('file'))
- total = len(all_files)
- downloaded = 0
- threads = 5
- c = math.ceil(total / threads)
- for i in range(0, threads):
- files = all_files[i * c:i * c + c]
- thread = threading.Thread(target=download, args=(files, folder))
- thread.start()
- print("Downloading files from %s" % manifest)
- while True:
- time.sleep(1)
- completed = 50 * downloaded // total
- print('\r[%s] %s%% (%s of %s)' % ('#' * completed + '.' * (50 - completed), round(100 * downloaded / total, 1), downloaded, total), end='', flush=True)
- if downloaded == total:
- break
- print()
|