Initial
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/.idea/
|
||||||
|
/tests/
|
||||||
|
|
||||||
|
poetry.lock
|
||||||
|
|
||||||
|
*/__pycache__/
|
||||||
1
README.md
Normal file
1
README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[nekomata is now in early-dev state](https://nekomata.kotikot.com/)
|
||||||
4
neko_configparser/__init__.py
Normal file
4
neko_configparser/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
from .neko.interfaces import ConfigParserInterface
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['ConfigParserInterface']
|
||||||
1
neko_configparser/modules/__init__.py
Normal file
1
neko_configparser/modules/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pass
|
||||||
19
neko_configparser/modules/toml_parser.py
Normal file
19
neko_configparser/modules/toml_parser.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import toml
|
||||||
|
|
||||||
|
|
||||||
|
class TomlConfig(dict):
|
||||||
|
def __init__(self, config_path: str = 'config.neko.toml', _config: dict = None):
|
||||||
|
try:
|
||||||
|
if _config is None:
|
||||||
|
super().__init__(**toml.load(config_path))
|
||||||
|
else:
|
||||||
|
super().__init__(**_config)
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def __getattr__(self, item):
|
||||||
|
if type(self.get(item)) is not dict:
|
||||||
|
return self.get(item)
|
||||||
|
else:
|
||||||
|
return TomlConfig(_config=self.get(item))
|
||||||
79
neko_configparser/modules/writer.py
Normal file
79
neko_configparser/modules/writer.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import toml
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
|
||||||
|
def _update_dicts(dict1, dict2):
|
||||||
|
"""
|
||||||
|
Ensures that dict1 exists in dict2 or merges them in right way
|
||||||
|
"""
|
||||||
|
for key in dict1:
|
||||||
|
if key not in dict2 and not isinstance(dict1[key], WriteTomlConfig):
|
||||||
|
dict2[key] = dict1[key]
|
||||||
|
elif isinstance(dict1[key], dict) and isinstance(dict2[key], dict):
|
||||||
|
_update_dicts(dict1[key], dict2[key])
|
||||||
|
|
||||||
|
|
||||||
|
class WriteTomlConfig(dict):
|
||||||
|
def __init__(self, filename: str = 'config.neko.toml'):
|
||||||
|
self.__filename = filename
|
||||||
|
self.__parent = None
|
||||||
|
super().__init__()
|
||||||
|
self.__load_from_file(filename)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __create_subsidiary(cls, data, parent):
|
||||||
|
d = cls(None) # type: ignore
|
||||||
|
d.__parent = parent
|
||||||
|
|
||||||
|
for key, value in data.items():
|
||||||
|
if isinstance(value, dict):
|
||||||
|
d[key] = cls.__create_subsidiary(value, parent=parent)
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
val = super().__getitem__(key)
|
||||||
|
return val
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
value = type(self).__create_subsidiary(value, parent=self)
|
||||||
|
super().__setitem__(key, value)
|
||||||
|
self.__propagate_write()
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
super().__delitem__(key)
|
||||||
|
self.__propagate_write()
|
||||||
|
|
||||||
|
def __propagate_write(self):
|
||||||
|
if self.__parent:
|
||||||
|
self.__parent.__propagate_write()
|
||||||
|
else:
|
||||||
|
self.__write()
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
standard_dict = {}
|
||||||
|
for key, value in self.items():
|
||||||
|
if isinstance(value, type(self)):
|
||||||
|
standard_dict[key] = value.to_dict()
|
||||||
|
else:
|
||||||
|
standard_dict[key] = value
|
||||||
|
return standard_dict
|
||||||
|
|
||||||
|
def __write(self):
|
||||||
|
with open(self.__filename, 'w') as f:
|
||||||
|
toml.dump(self.to_dict(), f)
|
||||||
|
|
||||||
|
def __load_from_file(self, filename=None):
|
||||||
|
if not filename:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
data = toml.load(filename)
|
||||||
|
for key, value in data.items():
|
||||||
|
self[key] = value
|
||||||
|
except FileNotFoundError:
|
||||||
|
open(filename, 'w+').close()
|
||||||
|
|
||||||
|
def ensure(self, data: Dict[str, Any]):
|
||||||
|
_update_dicts(data, self)
|
||||||
|
self.__propagate_write()
|
||||||
1
neko_configparser/neko/__init__.py
Normal file
1
neko_configparser/neko/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pass
|
||||||
30
neko_configparser/neko/interfaces.py
Normal file
30
neko_configparser/neko/interfaces.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from ..modules.toml_parser import TomlConfig
|
||||||
|
from ..modules.writer import WriteTomlConfig
|
||||||
|
from typing import Dict, Any
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigParserInterface:
|
||||||
|
@staticmethod
|
||||||
|
def parse_config(config_path: str = 'config.neko.toml') -> TomlConfig:
|
||||||
|
"""
|
||||||
|
Get toml configuration in our handy representation
|
||||||
|
:param config_path:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return TomlConfig(config_path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ensure_config(
|
||||||
|
partition: str,
|
||||||
|
module_config: Dict[str, Any],
|
||||||
|
config_path: str = 'config.neko.toml'
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Validates your module config and adds values if needed
|
||||||
|
:param partition: Your module name or any name under which you want to see this
|
||||||
|
key-value configuration table
|
||||||
|
:param module_config: Dictionary of default config keys and values, so they will
|
||||||
|
be added and verified in config
|
||||||
|
:param config_path: Path of config, if you want to use custom
|
||||||
|
"""
|
||||||
|
WriteTomlConfig(config_path).ensure({partition: module_config})
|
||||||
17
pyproject.toml
Normal file
17
pyproject.toml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "neko-configparser"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["hhh"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.11"
|
||||||
|
toml = "^0.10.2"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
rich = "^13.7.0"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
Reference in New Issue
Block a user