Fix the objref issue.
[pti/o2.git] / o2common / config / base.py
1 # Copyright (C) 2022 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 import os
16 import configparser
17
18
19 class Error(Exception):
20     """Base class for cfg exceptions."""
21
22     def __init__(self, msg=None):
23         self.msg = msg
24
25     def __str__(self):
26         return self.msg
27
28
29 class NoSuchOptError(Error, AttributeError):
30     """Raised if an opt which doesn't exist is referenced."""
31
32     def __init__(self, opt_name, group=None):
33         self.opt_name = opt_name
34         self.group = group
35
36     def __str__(self):
37         group_name = 'DEFAULT' if self.group is None else self.group.name
38         return "no such option %s in group [%s]" % (self.opt_name, group_name)
39
40
41 class NoSuchConfigFile(Error):
42     """Raised if the config file does not exist."""
43
44     def __init__(self, file_path):
45         self.file_path = file_path
46
47     def __str__(self):
48         return "no such file %s exist" % self.file_path
49
50
51 class Section:
52     def __init__(self, section: str) -> None:
53         self.group_name = section
54         self._options = {}
55
56     def _set(self, name, value):
57         opt = getattr(self, name)
58         if opt is None:
59             setattr(self, name, value)
60         if name not in self._options:
61             self._options[name] = value
62
63     def _get(self, name):
64         name = name.lower()
65         if name in self._options:
66             return self._options[name]
67
68     def __getattr__(self, name):
69         try:
70             return self._get(name)
71         except ValueError:
72             raise
73         except Exception:
74             raise NoSuchOptError(name, self.group_name)
75
76
77 class Config:
78     def __init__(self) -> None:
79         self.__cache = {'b': 456}
80         self._sections = {}
81
82     def _set(self, section, name='', value=''):
83         group = getattr(self, section)
84         if group is None:
85             group = Section(section)
86             setattr(self, section, group)
87         if section not in self._sections:
88             self._sections[section] = group
89         if name != '':
90             setattr(group, name, value)
91         return group
92
93     def _get(self, name):
94         if name in self._sections:
95             return self._sections(name)
96
97         if name in self.__cache:
98             return self.__cache(name)
99
100     def __getattr__(self, name):
101         try:
102             return self._get(name)
103         except ValueError:
104             raise
105         except Exception:
106             raise NoSuchOptError(name)
107
108     def load(self, file_path):
109         if not os.path.exists(file_path):
110             raise NoSuchConfigFile(file_path)
111         conf = configparser.ConfigParser()
112         conf.read(file_path)
113         default_group = self._set('DEFAULT')
114         for option in conf['DEFAULT']:
115             default_group._set(option, conf['DEFAULT'][option])
116         for section in conf.sections():
117             group = self._set(section)
118             for option in conf[section]:
119                 group._set(option, conf[section][option])
120
121
122 if __name__ == "__main__":
123     conf = Config()
124     # conf._set('default', 'a', 123)
125
126     # print(conf.default.a)
127     # print(conf.b)
128
129     # conf = configparser.ConfigParser()
130     # conf.read('configs/o2app.conf')
131     # print(conf)
132     # print(conf['DEFAULT'].__dict__)
133     # print(conf['DEFAULT']['test'])
134     conf.load('configs/o2app.conf')
135     print(conf.API.test)
136     print(conf.DEFAULT.test)
137     print(conf.PUBSUB.ooo)
138     print(conf.DEFAULT.oCloudGlobalID)