#! /usr/bin/env python3 import sys import os import re import json import fnmatch from subprocess import run from multiprocessing import Pool, cpu_count if not os.path.isfile("data/nav.dat"): print("ERROR: no data/nav.dat file") sys.exit(1) def find(pattern, path): result = [] for root, dirs, files in os.walk(path): for name in files: if fnmatch.fnmatch(name, pattern): result.append(os.path.join(root, name)) return result def unique(it): s = set() for el in it: if el not in s: s.add(el) yield el def bash(cmd): run(cmd, shell=True) def buildApt(apt): aptId = changed[apt]["id"] path = "tmp/" + apt + "/" bash("mkdir -p " + path + "/work") bash("ln -sf $(pwd)/work/SRTM-3 " + path + "/work") bash("wget https://gateway.x-plane.com/apiv1/scenery/" + str(aptId) + " -O " + path + apt + ".json > logs/" + apt + ".log 2>&1") try: with open(path + apt + ".json") as json_data: source = json.load(json_data) with open(path + apt + ".tmp", "w") as tmp: tmp.write(source["scenery"]["masterZipBlob"]) bash("cat " + path + apt + ".tmp | base64 -d -- > " + path + apt + ".zip") bash("cd " + path + " && unzip -o " + apt + ".zip >> ../../logs/" + apt + ".log 2>&1") bash("cd " + path + " && ../../dsf2aptdat.py -i " + apt + ">> ../../logs/" + apt + ".log 2>&1") bash("mv -f " + path + apt + ".dat data/airports/") bash("/terragear/run_genapts.sh --input=$(pwd)/data/airports/" + apt + ".dat --work=$(pwd)/" + path + "work --clear-dem-path --dem-path=SRTM-3 >> logs/" + apt + ".log 2>&1") ind = find("*.ind", path + "work/AirportObj/") if len(ind) > 0: match = re.match(".*Obj/([we]\d{3}[sn]\d{2}/[we]\d{3}[sn]\d{2})/(\d+)\.ind", ind[0]) if match != None: bash("mkdir -p output/Terrain/" + match.group(1)) bash("mv " + path + "work/AirportObj/" + match.group(1) + "/" + apt + ".btg.gz output/Terrain/" + match.group(1)) bash("mkdir -p stg/" + match.group(1) + "/" + match.group(2)) bash("mv " + ind[0] + " stg/" + match.group(1) + "/" + match.group(2) + "/" + apt + ".stg") bash("rm -rf " + path) bash("aptdat2airportsxml --overwrite -n data/nav.dat -o output/ -d /terragear/install/flightgear/fgdata/ -e /terragear/install/flightgear/bin/fgelev -i data/airports/" + apt + ".dat >> logs/" + apt + ".log 2>&1") return match.group(1) + "/" + match.group(2) except (ValueError, json.decoder.JSONDecodeError): print("ERROR: Invalid responce for " + apt + " recieved") bash("wget https://gateway.x-plane.com/apiv1/airports -O tmp/airports.json") try: with open("tmp/airports.json") as json_data: source = json.load(json_data) except ValueError: print("ERROR: Invalid airports file recieved") sys.exit(1) airports = {} if os.path.isfile("data/airports-done.json"): try: with open("data/airports-done.json") as json_data: airports = json.load(json_data) except ValueError: print("ERROR: Invalid airports-done.json file") sys.exit(1) changed = {} for apt in source["airports"]: airport = {} airport["id"] = apt["RecommendedSceneryId"] if (not apt["AirportCode"] in airports or airports[apt["AirportCode"]]["id"] != apt["RecommendedSceneryId"]) and apt["ApprovedSceneryCount"] > 0: airports[apt["AirportCode"]] = airport changed[apt["AirportCode"]] = airport print("Added " + apt["AirportCode"]) with Pool(processes=cpu_count()) as pool: tiles = set(pool.map(buildApt, changed)) print("INFO: Updating .stg files...") if changed != {}: for tile in tiles: if tile != None: bash("cat stg/" + tile + "/*.stg > output/Terrain/" + tile + ".stg") print("INFO: Generating new apt.dat.gz...") bash("mkdir -p output/NavData/apt") bash("rm -f output/NavData/apt/apt.dat.gz") bash('''echo "I 1130 Generated by aptupd " > output/NavData/apt/apt.dat''') bash("ls data/airports/|parallel -j 1 ./append-apt.sh data/airports/{}") bash("gzip output/NavData/apt/apt.dat") bash("rm -rf tmp/*") with open("data/airports-done.json", "w") as f: json.dump(airports, f)