136 lines
4.6 KiB
Python
136 lines
4.6 KiB
Python
from argparse import ArgumentParser
|
|
from os import path, sep
|
|
|
|
|
|
class Parse:
|
|
"""
|
|
Parser of configs, arguments, parameters
|
|
"""
|
|
def __init__(self, parameters, block: str = None):
|
|
"""
|
|
Object constructor
|
|
:param parameters: dictionary as "key":"value" or
|
|
ArgumentParser class object or
|
|
string path to the file or
|
|
string as "var1=val1;var2=val2"
|
|
:param block: string name of target block from text
|
|
"""
|
|
self.data = {}
|
|
if type(parameters) is dict:
|
|
self._dict2dict(parameters)
|
|
if type(parameters) is ArgumentParser:
|
|
self._dict2dict(self.argv2dict(parameters))
|
|
if type(parameters) is str:
|
|
if path.exists(parameters):
|
|
self._dict2dict(self.strs2dict(self.conf2strs(parameters), block))
|
|
else:
|
|
self._dict2dict(self.strs2dict(parameters, block))
|
|
|
|
def __str__(self):
|
|
"""
|
|
Overrides method for print(object)
|
|
:return: string with contents of the object's dictionary
|
|
"""
|
|
string = ''
|
|
for key, val in self.data.items():
|
|
string += str(type(val)) + ' ' + str(key) + ' = ' + str(val) + '\n'
|
|
return string
|
|
|
|
def _dict2dict(self, dictionary: dict):
|
|
"""
|
|
Updates or adds dictionary data
|
|
:param dictionary: dictionary as "key":"value"
|
|
:return: None
|
|
"""
|
|
self.data.update(dictionary)
|
|
|
|
def expand(self, store: str = None):
|
|
"""
|
|
Expand dictionary "key":"name.conf" to dictionary "key":{subkey: subval}
|
|
:param store: string path to directory with name.conf
|
|
:return: expanded dictionary as "key":{subkey: subval}
|
|
"""
|
|
for key in self.data:
|
|
if store:
|
|
config = store + sep + self.data[key]
|
|
else:
|
|
config = self.data[key]
|
|
with open(config) as file:
|
|
self.data[key] = Parse(file.read()).data
|
|
return self.data
|
|
|
|
@classmethod
|
|
def argv2dict(cls, parser: ArgumentParser):
|
|
"""
|
|
Converts startup arguments to a dictionary
|
|
:param parser: argparse.ArgumentParser class object
|
|
:return: dictionary as "key":"value"
|
|
"""
|
|
parser = ArgumentParser(add_help=False, parents=[parser])
|
|
return vars(parser.parse_args())
|
|
|
|
@classmethod
|
|
def conf2strs(cls, config: str):
|
|
"""
|
|
Builds a dictionary from a file containing parameters
|
|
:param config: string path to the file
|
|
:return: string as "var1=val1;\nvar2=val2;"
|
|
"""
|
|
with open(config) as file:
|
|
raw = file.read()
|
|
strs = ''
|
|
for line in raw.splitlines():
|
|
if not line.lstrip().startswith('#'):
|
|
strs += line + '\n'
|
|
return strs
|
|
|
|
@classmethod
|
|
def strs2dict(cls, strings: str, blockname: str):
|
|
"""
|
|
Builds a dictionary from a strings containing parameters
|
|
:param strings: string as "var1=val1;var2=val2;"
|
|
:param blockname: string name of target block from text
|
|
:return: dictionary as "key":"value"
|
|
"""
|
|
dictionary = {}
|
|
if blockname:
|
|
strings = cls.block(blockname, strings)
|
|
for line in strings.replace('\n', ';').split(';'):
|
|
if not line.lstrip().startswith('#') and "=" in line:
|
|
dictionary[line.split('=')[0].strip()] = line.split('=')[1].strip().split(';')[0].strip()
|
|
return dictionary
|
|
|
|
@classmethod
|
|
def str2bool(cls, value: str):
|
|
"""
|
|
Converts a string value to boolean
|
|
:param value: string containing "true" or "false", "yes" or "no", "1" or "0"
|
|
:return: bool True or False
|
|
"""
|
|
return str(value).lower() in ("true", "yes", "1")
|
|
|
|
@classmethod
|
|
def block(cls, blockname: str, text: str):
|
|
"""
|
|
Cuts a block of text between line [blockname] and line [next block] or EOF
|
|
:param blockname: string in [] after which the block starts
|
|
:param text: string of text from which the block is needed
|
|
:return: string of text between line [block name] and line [next block]
|
|
"""
|
|
level = 1
|
|
save = False
|
|
result = ''
|
|
for line in text.splitlines():
|
|
if line.startswith('[') and blockname in line:
|
|
level = line.count('[')
|
|
save = True
|
|
elif line.startswith('[') and '['*level in line:
|
|
save = False
|
|
elif save:
|
|
result += line + '\n'
|
|
return result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pass
|