| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 | # SPDX-License-Identifier: AGPL-3.0-or-later"""build environment used by shell scripts"""# set pathimport sysimport importlib.utilimport refrom pathlib import Pathrepo_root = Path(__file__).resolve().parent.parentdef main(setting_name):    settings_path = repo_root / "searx" / "settings.yml"    with open(settings_path) as f:        settings = parse_yaml(f.read())    print(get_setting_value(settings, setting_name))def get_setting_value(settings, name):    value = settings    for a in name.split("."):        value = value[a]    if value is True:        value = "1"    elif value is False:        value = ""    return valuedef parse_yaml(yaml_str):    """A simple YAML parser that converts a YAML string to a Python dictionary.    This parser can handle nested dictionaries, but does not handle list or JSON    like structures.    Good enough parser to get the values of server.base_url, server.port and    server.bind_address    """    def get_type_and_value_without_comment(line):        """Extract value without comment and quote        Returns a tuple:        1. str or None: str when the value is written inside quote, None otherwise        2. the value without quote if any        """        match = re.search(r"\"(.*)\"(\s+#)?|\'(.*)\'(\s+#)?|([^#]*)(\s+#)?", line)        if match:            g = match.groups()            if g[0] is not None:                return str, g[0]            elif g[2] is not None:                return str, g[2]            elif g[4] is not None:                return None, g[4].strip()        return None, line.strip()    # fmt: off    true_values = ("y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "on", "On", "ON",)    false_values = ("n", "N", "no", "No", "NO", "false", "False", "FALSE", "off", "Off", "OFF",)    # fmt: on    def process_line(line):        """Extract key and value from a line, considering its indentation."""        if ": " in line:            key, value = line.split(": ", 1)            key = key.strip()            value_type, value = get_type_and_value_without_comment(value)            if value in true_values and value_type is None:                value = True            elif value in false_values and value_type is None:                value = False            elif value.replace(".", "").isdigit() and value_type is None:                for t in (int, float):                    try:                        value = t(value)                        break                    except ValueError:                        continue            return key, value        return None, None    def get_indentation_level(line):        """Determine the indentation level of a line."""        return len(line) - len(line.lstrip())    yaml_dict = {}    lines = yaml_str.split("\n")    stack = [yaml_dict]    for line in lines:        if not line.strip():            continue  # Skip empty lines        indentation_level = get_indentation_level(line)        # Assuming 2 spaces per indentation level        # see .yamllint.yml        current_level = indentation_level // 2        # Adjust the stack based on the current indentation level        while len(stack) > current_level + 1:            stack.pop()        if line.endswith(":"):            key = line[0:-1].strip()            new_dict = {}            stack[-1][key] = new_dict            stack.append(new_dict)        else:            key, value = process_line(line)            if key is not None:                stack[-1][key] = value    return yaml_dictif __name__ == "__main__":    main(sys.argv[1])
 |