mirror of
https://github.com/zoffline/zwift-offline.git
synced 2026-01-11 04:34:00 -08:00
60 lines
2.4 KiB
Python
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()
|