summaryrefslogtreecommitdiff
path: root/utils/get_setting.py
blob: 94c894e3e9980a1ecc227d79fa208bc5db0d9146 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# SPDX-License-Identifier: AGPL-3.0-or-later
"""build environment used by shell scripts
"""

# set path
import sys
import importlib.util
import re

from pathlib import Path

repo_root = Path(__file__).resolve().parent.parent


def 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 value


def 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_dict


if __name__ == "__main__":
    main(sys.argv[1])