get_gameassets.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import os
  2. import time
  3. import math
  4. import signal
  5. import threading
  6. import xml.etree.ElementTree as ET
  7. from urllib3 import PoolManager
  8. from binascii import crc32
  9. def sigint_handler(num, frame):
  10. os._exit(0)
  11. signal.signal(signal.SIGINT, sigint_handler)
  12. def download(files, folder):
  13. global downloaded
  14. manager = PoolManager()
  15. for file in files:
  16. path = file.find('path').text
  17. length = int(file.find('length').text)
  18. checksum = int(file.find('checksum').text) % (1 << 32)
  19. file_name = os.path.join(local_path, folder, path.replace('\\', os.sep))
  20. dir_name = os.path.dirname(file_name)
  21. if not os.path.isdir(dir_name):
  22. os.makedirs(dir_name)
  23. 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):
  24. open(file_name, 'wb').write(manager.request('GET', '%s%s/%s' % (base_url, folder, path.replace('\\', '/'))).data)
  25. downloaded += 1
  26. base_url = 'http://cdn.zwift.com/gameassets/Zwift_Updates_Root/'
  27. local_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'cdn', 'gameassets', 'Zwift_Updates_Root')
  28. for file in ['Zwift_ver_cur.xml', 'ZwiftMac_ver_cur.xml']:
  29. tree = ET.parse(os.path.join(local_path, file))
  30. root = tree.getroot()
  31. manifest = root.get('manifest')
  32. manifest_checksum = int(root.get('manifest_checksum')) % (1 << 32)
  33. manifest_file = os.path.join(local_path, manifest)
  34. while not os.path.isfile(manifest_file) or crc32(open(manifest_file, 'rb').read()) != manifest_checksum:
  35. open(manifest_file, 'wb').write(PoolManager().request('GET', base_url + manifest).data)
  36. tree = ET.parse(manifest_file)
  37. root = tree.getroot()
  38. folder = root.get('folder')
  39. all_files = list(root.iter('file'))
  40. total = len(all_files)
  41. downloaded = 0
  42. threads = 5
  43. c = math.ceil(total / threads)
  44. for i in range(0, threads):
  45. files = all_files[i * c:i * c + c]
  46. thread = threading.Thread(target=download, args=(files, folder))
  47. thread.start()
  48. print("Downloading files from %s" % manifest)
  49. while True:
  50. time.sleep(1)
  51. completed = 50 * downloaded // total
  52. print('\r[%s] %s%% (%s of %s)' % ('#' * completed + '.' * (50 - completed), round(100 * downloaded / total, 1), downloaded, total), end='', flush=True)
  53. if downloaded == total:
  54. break
  55. print()