import glob import os import re import subprocess import sys import time from collections import OrderedDict if sys.version_info[0] < 3: use_python3 = "Must be using Python 3" print(use_python3) time.sleep(1.5) raise Exception(use_python3) try: from lupa import LuaRuntime except ImportError: print("lupa not found, trying to install it...") subprocess.call([sys.executable, "-m", "pip", "install", "lupa", "--user"]) try: from lupa import LuaRuntime except ImportError as e: print("failed to import lupa, file an issue if you will") time.sleep(1.5) raise e indent = " " def format_data(data): if isinstance(data, str): value = "\"" + data + "\"" elif isinstance(data, bool): if data: value = "true" else: value = "false" else: value = data return value class ModInfoConfig: def __eq__(self, other): return self.options == other.options and \ self.name == other.name and \ self.label == other.label and \ self.default == other.default def __init__(self, name=None, label=None, default=None, options=None): if options is None: options = [] self.name = name self.label = label self.default = default self.options = options def __str__(self) -> str: return "\n".join(self.to_lua_string_parts()) def _to_lua_string_config_options(self): rets = [] for option in self.options: rets.append( "-- description = %s, data = %s" % (option["description"], format_data(option["data"]))) return rets def to_lua_string_parts(self): rets = [] if self.label or self.name: rets.append("-- %s" % (self.label or self.name)) rets.extend(self._to_lua_string_config_options()) if self.name != "": rets.append("[\"%s\"] = %s," % (self.name, format_data(self.default))) return rets def merge(self, other): self.name = self.name or other.name self.label = self.label or other.label self.default = self.default if self.default is not None else other.default self.options = other.options or self.options return self @staticmethod def load_from_existing_overrides_options_item(entry): name = entry[0] default = entry[1] return ModInfoConfig(name=name, default=default) @staticmethod def load_from_existing_overrides_options_items(entries): return OrderedDict( map(lambda x: (x.name, x), map(ModInfoConfig.load_from_existing_overrides_options_item, entries))) @staticmethod def _parse_config_options(options_lua_iter): return list(map(lambda x: { "description": x.description, "data": x.data }, options_lua_iter)) @staticmethod def load_from_config_lua(config_lua): return ModInfoConfig( name=config_lua.name, label=config_lua.label, default=config_lua.default, options=ModInfoConfig._parse_config_options(config_lua.options.values()) ) @staticmethod def load_from_configs_lua(configs_lua): return list(map(ModInfoConfig.load_from_config_lua, configs_lua)) class ModInfo: def __init__(self, name=None, configs=None, enabled=False): if configs is None: configs = OrderedDict() self.name = name self.configs = configs self.workshop_id = "" self.enabled = enabled def __str__(self): return "\n".join(self.to_lua_string_parts()) def set_workshop_id(self, folder_name): self.workshop_id = folder_name @staticmethod def load_from_modinfo_file(filepath: str): print("processing", filepath) workshop_id = os.path.basename(os.path.dirname(filepath)) with open(filepath, "r", encoding='UTF-8', errors='ignore') as modinfo_file: # Health Info has invalid escape sequence in the string... sanitize it so lua interpreter modinfo_str = re.sub('(?