##// END OF EJS Templates
helpers: moved duplicated code to type_utils
super-admin -
r1111:a5985c44 python3
parent child Browse files
Show More
@@ -0,0 +1,62 b''
1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 # Copyright (C) 2014-2020 RhodeCode GmbH
3 #
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software Foundation,
16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18
19 import logging
20
21 log = logging.getLogger(__name__)
22
23
24 def str2bool(str_):
25 """
26 returns True/False value from given string, it tries to translate the
27 string into boolean
28
29 :param str_: string value to translate into boolean
30 :rtype: boolean
31 :returns: boolean from given string
32 """
33 if str_ is None:
34 return False
35 if str_ in (True, False):
36 return str_
37 str_ = str(str_).strip().lower()
38 return str_ in ('t', 'true', 'y', 'yes', 'on', '1')
39
40
41 def aslist(obj, sep=None, strip=True) -> list:
42 """
43 Returns given string separated by sep as list
44
45 :param obj:
46 :param sep:
47 :param strip:
48 """
49 if isinstance(obj, str):
50 if obj in ['', ""]:
51 return []
52
53 lst = obj.split(sep)
54 if strip:
55 lst = [v.strip() for v in lst]
56 return lst
57 elif isinstance(obj, (list, tuple)):
58 return obj
59 elif obj is None:
60 return []
61 else:
62 return [obj] No newline at end of file
@@ -1,208 +1,170 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2020 RhodeCode GmbH
3 # Copyright (C) 2010-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import textwrap
22 import textwrap
23 import string
23 import string
24 import functools
24 import functools
25 import logging
25 import logging
26 import tempfile
26 import tempfile
27 import logging.config
27 import logging.config
28
29 from vcsserver.type_utils import str2bool, aslist
30
28 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
29
32
30 # skip keys, that are set here, so we don't double process those
33 # skip keys, that are set here, so we don't double process those
31 set_keys = {
34 set_keys = {
32 '__file__': ''
35 '__file__': ''
33 }
36 }
34
37
35
38
36 def str2bool(_str):
37 """
38 returns True/False value from given string, it tries to translate the
39 string into boolean
40
41 :param _str: string value to translate into boolean
42 :rtype: boolean
43 :returns: boolean from given string
44 """
45 if _str is None:
46 return False
47 if _str in (True, False):
48 return _str
49 _str = str(_str).strip().lower()
50 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
51
52
53 def aslist(obj, sep=None, strip=True):
54 """
55 Returns given string separated by sep as list
56
57 :param obj:
58 :param sep:
59 :param strip:
60 """
61 if isinstance(obj, str):
62 if obj in ['', ""]:
63 return []
64
65 lst = obj.split(sep)
66 if strip:
67 lst = [v.strip() for v in lst]
68 return lst
69 elif isinstance(obj, (list, tuple)):
70 return obj
71 elif obj is None:
72 return []
73 else:
74 return [obj]
75
76
77 class SettingsMaker(object):
39 class SettingsMaker(object):
78
40
79 def __init__(self, app_settings):
41 def __init__(self, app_settings):
80 self.settings = app_settings
42 self.settings = app_settings
81
43
82 @classmethod
44 @classmethod
83 def _bool_func(cls, input_val):
45 def _bool_func(cls, input_val):
84 if isinstance(input_val, bytes):
46 if isinstance(input_val, bytes):
85 # decode to str
47 # decode to str
86 input_val = input_val.decode('utf8')
48 input_val = input_val.decode('utf8')
87 return str2bool(input_val)
49 return str2bool(input_val)
88
50
89 @classmethod
51 @classmethod
90 def _int_func(cls, input_val):
52 def _int_func(cls, input_val):
91 return int(input_val)
53 return int(input_val)
92
54
93 @classmethod
55 @classmethod
94 def _list_func(cls, input_val, sep=','):
56 def _list_func(cls, input_val, sep=','):
95 return aslist(input_val, sep=sep)
57 return aslist(input_val, sep=sep)
96
58
97 @classmethod
59 @classmethod
98 def _string_func(cls, input_val, lower=True):
60 def _string_func(cls, input_val, lower=True):
99 if lower:
61 if lower:
100 input_val = input_val.lower()
62 input_val = input_val.lower()
101 return input_val
63 return input_val
102
64
103 @classmethod
65 @classmethod
104 def _float_func(cls, input_val):
66 def _float_func(cls, input_val):
105 return float(input_val)
67 return float(input_val)
106
68
107 @classmethod
69 @classmethod
108 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
70 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
109
71
110 # ensure we have our dir created
72 # ensure we have our dir created
111 if not os.path.isdir(input_val) and ensure_dir:
73 if not os.path.isdir(input_val) and ensure_dir:
112 os.makedirs(input_val, mode=mode)
74 os.makedirs(input_val, mode=mode)
113
75
114 if not os.path.isdir(input_val):
76 if not os.path.isdir(input_val):
115 raise Exception('Dir at {} does not exist'.format(input_val))
77 raise Exception('Dir at {} does not exist'.format(input_val))
116 return input_val
78 return input_val
117
79
118 @classmethod
80 @classmethod
119 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
81 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
120 dirname = os.path.dirname(input_val)
82 dirname = os.path.dirname(input_val)
121 cls._dir_func(dirname, ensure_dir=ensure_dir)
83 cls._dir_func(dirname, ensure_dir=ensure_dir)
122 return input_val
84 return input_val
123
85
124 @classmethod
86 @classmethod
125 def _key_transformator(cls, key):
87 def _key_transformator(cls, key):
126 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
88 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
127
89
128 def maybe_env_key(self, key):
90 def maybe_env_key(self, key):
129 # now maybe we have this KEY in env, search and use the value with higher priority.
91 # now maybe we have this KEY in env, search and use the value with higher priority.
130 transformed_key = self._key_transformator(key)
92 transformed_key = self._key_transformator(key)
131 envvar_value = os.environ.get(transformed_key)
93 envvar_value = os.environ.get(transformed_key)
132 if envvar_value:
94 if envvar_value:
133 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
95 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
134
96
135 return envvar_value
97 return envvar_value
136
98
137 def env_expand(self):
99 def env_expand(self):
138 replaced = {}
100 replaced = {}
139 for k, v in self.settings.items():
101 for k, v in self.settings.items():
140 if k not in set_keys:
102 if k not in set_keys:
141 envvar_value = self.maybe_env_key(k)
103 envvar_value = self.maybe_env_key(k)
142 if envvar_value:
104 if envvar_value:
143 replaced[k] = envvar_value
105 replaced[k] = envvar_value
144 set_keys[k] = envvar_value
106 set_keys[k] = envvar_value
145
107
146 # replace ALL keys updated
108 # replace ALL keys updated
147 self.settings.update(replaced)
109 self.settings.update(replaced)
148
110
149 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
111 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
150 """
112 """
151 Helper to enable debug on running instance
113 Helper to enable debug on running instance
152 :return:
114 :return:
153 """
115 """
154
116
155 if not str2bool(self.settings.get('logging.autoconfigure')):
117 if not str2bool(self.settings.get('logging.autoconfigure')):
156 log.info('logging configuration based on main .ini file')
118 log.info('logging configuration based on main .ini file')
157 return
119 return
158
120
159 if logging_conf is None:
121 if logging_conf is None:
160 logging_conf = self.settings.get('logging.logging_conf_file') or ''
122 logging_conf = self.settings.get('logging.logging_conf_file') or ''
161
123
162 if not os.path.isfile(logging_conf):
124 if not os.path.isfile(logging_conf):
163 log.error('Unable to setup logging based on %s, '
125 log.error('Unable to setup logging based on %s, '
164 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
126 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
165 return
127 return
166
128
167 with open(logging_conf, 'rt') as f:
129 with open(logging_conf, 'rt') as f:
168 ini_template = textwrap.dedent(f.read())
130 ini_template = textwrap.dedent(f.read())
169 ini_template = string.Template(ini_template).safe_substitute(
131 ini_template = string.Template(ini_template).safe_substitute(
170 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
132 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
171 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
133 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
172 )
134 )
173
135
174 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
136 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
175 log.info('Saved Temporary LOGGING config at %s', f.name)
137 log.info('Saved Temporary LOGGING config at %s', f.name)
176 f.write(ini_template)
138 f.write(ini_template)
177
139
178 logging.config.fileConfig(f.name)
140 logging.config.fileConfig(f.name)
179 os.remove(f.name)
141 os.remove(f.name)
180
142
181 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
143 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
182 input_val = self.settings.get(key, default)
144 input_val = self.settings.get(key, default)
183
145
184 if default_when_empty and not input_val:
146 if default_when_empty and not input_val:
185 # use default value when value is set in the config but it is empty
147 # use default value when value is set in the config but it is empty
186 input_val = default
148 input_val = default
187
149
188 parser_func = {
150 parser_func = {
189 'bool': self._bool_func,
151 'bool': self._bool_func,
190 'int': self._int_func,
152 'int': self._int_func,
191 'list': self._list_func,
153 'list': self._list_func,
192 'list:newline': functools.partial(self._list_func, sep='/n'),
154 'list:newline': functools.partial(self._list_func, sep='/n'),
193 'list:spacesep': functools.partial(self._list_func, sep=' '),
155 'list:spacesep': functools.partial(self._list_func, sep=' '),
194 'string': functools.partial(self._string_func, lower=lower),
156 'string': functools.partial(self._string_func, lower=lower),
195 'dir': self._dir_func,
157 'dir': self._dir_func,
196 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
158 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
197 'file': self._file_path_func,
159 'file': self._file_path_func,
198 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
160 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
199 None: lambda i: i
161 None: lambda i: i
200 }[parser]
162 }[parser]
201
163
202 envvar_value = self.maybe_env_key(key)
164 envvar_value = self.maybe_env_key(key)
203 if envvar_value:
165 if envvar_value:
204 input_val = envvar_value
166 input_val = envvar_value
205 set_keys[key] = input_val
167 set_keys[key] = input_val
206
168
207 self.settings[key] = parser_func(input_val)
169 self.settings[key] = parser_func(input_val)
208 return self.settings[key]
170 return self.settings[key]
General Comments 0
You need to be logged in to leave comments. Login now