Files
zwift-offline/scripts/get_gameassets.py
2023-11-22 13:21:34 -03:00

60 lines
2.4 KiB
Python

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()