diff options
Diffstat (limited to 'reconfigure/configs/base.py')
-rw-r--r-- | reconfigure/configs/base.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/reconfigure/configs/base.py b/reconfigure/configs/base.py new file mode 100644 index 0000000..0753246 --- /dev/null +++ b/reconfigure/configs/base.py @@ -0,0 +1,71 @@ +import chardet + + +class Reconfig (object): + """ + Basic config class. Derivatives normally only need to override the constructor. + + Config data is loaded either from ``path`` or from ``content`` + + :param parser: overrides the Parser instance + :param includer: overrides the Includer instance + :param builder: overrides the Builder instance + :param path: config file path. Not compatible with ``content`` + :param content: config file content. Not compatible with ``path`` + """ + + def __init__(self, parser=None, includer=None, builder=None, path=None, content=None): + self.parser = parser + self.builder = builder + self.includer = includer + if self.includer is not None: + if not self.includer.parser: + self.includer.parser = self.parser + if path: + self.origin = path + self.content = None + else: + self.origin = None + self.content = content + + def load(self): + """ + Loads the config data, parses and builds it. Sets ``tree`` attribute to point to Data tree. + """ + if self.origin: + self.content = open(self.origin, 'r').read() + + try: + self.content = self.content.decode('utf8') + self.encoding = 'utf8' + except UnicodeDecodeError: + self.encoding = chardet.detect(self.content)['encoding'] + self.content = self.content.decode(self.encoding) + + self.nodetree = self.parser.parse(self.content) + if self.includer is not None: + self.nodetree = self.includer.compose(self.origin, self.nodetree) + if self.builder is not None: + self.tree = self.builder.build(self.nodetree) + return self + + def save(self): + """ + Unbuilds, stringifies and saves the config. If the config was loaded from string, returns ``{ origin: data }`` dict + """ + tree = self.tree + if self.builder is not None: + nodetree = self.builder.unbuild(tree) or self.nodetree + if self.includer is not None: + nodetree = self.includer.decompose(nodetree) + else: + nodetree = {self.origin: nodetree} + + result = {} + for k in nodetree: + result[k or self.origin] = self.parser.stringify(nodetree[k]).encode(self.encoding) + + if self.origin is not None: + for k in result: + open(k, 'w').write(result[k]) + return result |