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
|