Skip to content

Instantly share code, notes, and snippets.

@oldnapalm
Created October 25, 2024 23:42
Show Gist options
  • Select an option

  • Save oldnapalm/d2b1b2f8dc50389fed88eb067b89ddfe to your computer and use it in GitHub Desktop.

Select an option

Save oldnapalm/d2b1b2f8dc50389fed88eb067b89ddfe to your computer and use it in GitHub Desktop.
Get a list of Zwift routes on Windows
# Requires https://github.com/oldnapalm/zwift-offline/raw/refs/heads/master/scripts/wad_unpack.exe
import os
import xml.etree.ElementTree as ET
import re
import json
import subprocess
worlds = 'C:\\Program Files (x86)\\Zwift\\assets\\Worlds'
world_names = {
'1': 'Watopia',
'2': 'Richmond',
'3': 'London',
'4': 'New York',
'5': 'Innsbruck',
'6': 'Bologna',
'7': 'Yorkshire',
'8': 'Crit City',
'9': 'Makuri Islands',
'10': 'France',
'11': 'Paris',
'12': 'Gravel Mountain',
'13': 'Scotland'
}
def sorted_alphanumeric(data):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(data, key=alphanum_key)
data = {}
for directory in sorted_alphanumeric(os.listdir(worlds)):
world = directory[5:]
if os.path.isdir(os.path.join(worlds, directory)) and world in world_names:
wname = world_names[world]
data[wname] = []
subprocess.run(['wad_unpack.exe', os.path.join(worlds, directory, 'data_1.wad')])
routes = os.path.join('Worlds', directory, 'routes')
for file in sorted_alphanumeric(os.listdir(routes)):
with open(os.path.join(routes, file)) as f:
xml = f.read()
tree = ET.fromstring(re.sub(r"(<\?xml[^>]+\?>)", r"\1<root>", xml) + "</root>")
route = tree.find('route')
route_data = {
'name': route.get('name').strip(),
'distanceInMeters': round(float(route.get('distanceInMeters')), 1),
'leadinDistanceInMeters': round(float(route.get('leadinDistanceInMeters')), 1),
'ascentInMeters': round(float(route.get('ascentInMeters')), 1),
'leadinAscentInMeters': round(float(route.get('leadinAscentInMeters')), 1),
'sportType': 'running' if route.get('sportType') == '2' else 'cycling',
'eventOnly': route.get('eventOnly') == '1'
}
data[wname].append(route_data)
with open('routes.txt', 'w') as f:
json.dump(data, f, indent=2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment