#!/usr/bin/env python3 import json import yaml import os import sys from pathvalidate import sanitize_filename class IncludeTag: yaml_tag = '!include' def __init__(self, target): self.target = target @classmethod def to_yaml(cls, dumper, node): return dumper.represent_scalar(cls.yaml_tag, node.target) @classmethod def from_yaml(cls, loader, node): base_dir = os.path.dirname(loader.stream.name) target = os.path.join(base_dir, node.value) with open(target) as f: if target.endswith('.yaml'): return yaml.load(f, Loader=yaml.Loader) else: return f.read() yaml.add_constructor('!include', IncludeTag.from_yaml) yaml.add_representer(IncludeTag, IncludeTag.to_yaml) def uniqueName(obj): if 'SaveName' in obj: return obj['SaveName'] return f"{obj['Name']} {obj['Nickname']} {obj['GUID']}" def shouldRecurse(obj, subobject_prop): return subobject_prop in obj \ and obj.get('Name') not in ('Deck', 'DeckCustom') \ and len(obj[subobject_prop]) > 1 def recursivelyUnpackObject(parent_dir, obj, subobject_prop='ContainedObjects', base_name=None): def convertObjectsToIncludes(objects): for subObj in objects: filename = recursivelyUnpackObject(file_base_path, subObj) yield IncludeTag(os.path.join(obj_base_name, filename)) obj_base_name = base_name or sanitize_filename(uniqueName(obj)) file_base_path = os.path.join(parent_dir, obj_base_name) if shouldRecurse(obj, subobject_prop): os.makedirs(file_base_path, exist_ok=True) obj[subobject_prop] = list( convertObjectsToIncludes(obj[subobject_prop])) if 'LuaScript' in obj and len(obj['LuaScript']) > 0: with open(file_base_path + '.ttslua', 'w') as f: f.write(obj['LuaScript']) obj['LuaScript'] = IncludeTag(obj_base_name + '.ttslua') with open(file_base_path + '.yaml', 'w') as f: yaml.dump(obj, f) return obj_base_name + '.yaml' def unpackJson(json_file, output_name): with open(json_file) as f: data = json.load(f) recursivelyUnpackObject( '', data, subobject_prop='ObjectStates', base_name=output_name) def packYaml(yaml_file, output_json_file): with open(yaml_file) as f: data = yaml.load(f, Loader=yaml.Loader) with open(output_json_file, 'w') as f: json.dump(data, f, indent=2) def usage(): print(f"Usage: {sys.argv[0]} ") def main(): if len(sys.argv) != 4: usage() elif sys.argv[1] == 'unpack': unpackJson(sys.argv[2], sys.argv[3]) elif sys.argv[1] == 'pack': packYaml(sys.argv[2], sys.argv[3]) else: usage() if __name__ == '__main__': main()