summaryrefslogtreecommitdiffstats
path: root/iredis/config.py
blob: fefccdb52323c516454ce307b17903d9ee57bc53 (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
124
125
126
127
128
129
130
from importlib_resources import path
import os
import logging

from configobj import ConfigObj, ConfigObjError
from . import data as project_data

# TODO verbose logger to print to stdout
logger = logging.getLogger(__name__)


system_config_file = "/etc/iredisrc"
pwd_config_file = os.path.join(os.getcwd(), ".iredisrc")


class Config:
    """
    Global config, set once on start, then
    become readonly, never change again.

    :param raw: weather write raw bytes to stdout without any
        decoding.
    :param decode: How to decode bytes response.(For display and
        Completers)
        default is None, means show literal bytes. But completers
        will try use utf-8 decoding.
    """

    def __init__(self):
        self.raw = None
        self.completer_max = None
        # show command hint?
        self.newbie_mode = None
        self.rainbow = None
        self.retry_times = 2
        self.socket_keepalive = None
        self.decode = None
        self.no_info = None
        self.bottom_bar = None
        self.shell = None
        self.enable_pager = None
        self.pager = None

        self.warning = True

        self.no_version_reason = None
        self.log_location = None
        self.history_location = None
        self.completion_casing = None
        self.alias_dsn = None

        # ===bad code===
        # below are not configs, it's global state, it's wrong to write this
        # please do not add more global state.
        # FIXME this should be removed.
        # use client attributes instead.
        # use kwargs in render functions.

        # for transaction render
        self.queued_commands = []
        self.transaction = False
        # display zset withscores?
        self.withscores = False
        self.version = "Unknown"

    def __setter__(self, name, value):
        # for every time start a transaction
        # clear the queued commands first
        if name == "transaction" and value is True:
            self.queued_commands = []
        super().__setattr__(name, value)


config = Config()


def read_config_file(f):
    """Read a config file."""

    if isinstance(f, str):
        f = os.path.expanduser(f)

    try:
        config = ConfigObj(f, interpolation=False, encoding="utf8")
    except ConfigObjError as e:
        logger.error(
            "Unable to parse line {0} of config file " "'{1}'.".format(e.line_number, f)
        )
        logger.error("Using successfully parsed config values.")
        return e.config
    except (IOError, OSError) as e:
        logger.error(
            "You don't have permission to read " "config file '{0}'.".format(e.filename)
        )
        return None

    return config


def load_config_files(iredisrc):
    global config

    with path(project_data, "iredisrc") as p:
        config_obj = ConfigObj(str(p))

    for _file in [system_config_file, iredisrc, pwd_config_file]:
        _config = read_config_file(_file)
        if bool(_config) is True:
            config_obj.merge(_config)
            config_obj.filename = _config.filename

    config.raw = config_obj["main"].as_bool("raw")
    config.completer_max = config_obj["main"].as_int("completer_max")
    config.retry_times = config_obj["main"].as_int("retry_times")
    config.newbie_mode = config_obj["main"].as_bool("newbie_mode")
    config.rainbow = config_obj["main"].as_bool("rainbow")
    config.socket_keepalive = config_obj["main"].as_bool("socket_keepalive")
    config.no_info = config_obj["main"].as_bool("no_info")
    config.bottom_bar = config_obj["main"].as_bool("bottom_bar")
    config.warning = config_obj["main"].as_bool("warning")
    config.decode = config_obj["main"]["decode"]
    config.log_location = config_obj["main"]["log_location"]
    config.completion_casing = config_obj["main"]["completion_casing"]
    config.history_location = config_obj["main"]["history_location"]
    config.alias_dsn = config_obj["alias_dsn"]
    config.shell = config_obj["main"].as_bool("shell")
    config.pager = config_obj["main"].get("pager")
    config.enable_pager = config_obj["main"].as_bool("enable_pager")

    return config_obj