Last active
January 27, 2024 08:31
-
-
Save oldnapalm/556c58448a6ee09438b39e1c1c9ce3d0 to your computer and use it in GitHub Desktop.
Update Zwift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import platform | |
import time | |
import math | |
import signal | |
import threading | |
import xml.etree.ElementTree as ET | |
from urllib3 import PoolManager | |
from binascii import crc32 | |
if len(sys.argv) < 2: | |
print("Use %s <version>" % sys.argv[0]) | |
exit() | |
system = platform.system() | |
if system == 'Windows': | |
file = 'Zwift_ver_cur.%s.xml' % sys.argv[1] | |
local_path = 'C:\\Program Files (x86)\\Zwift' | |
elif system == 'Darwin': | |
file = 'ZwiftMac_ver_cur.%s.xml' % sys.argv[1] | |
local_path = '~/Library/Application Support/Zwift' | |
else: | |
print("Unsupported platform: %s" % system) | |
exit() | |
base_url = 'http://cdn.zwift.com/gameassets/Zwift_Updates_Root/' | |
open(os.path.join(local_path, file), 'wb').write(PoolManager().request('GET', base_url + file).data) | |
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, 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 | |
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment