implemented basis for config
This commit is contained in:
parent
aec62903e0
commit
31a7740760
53
documentation/config.md
Normal file
53
documentation/config.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
> This is bs, ima use dynaconf
|
||||||
|
|
||||||
|
# Concept
|
||||||
|
|
||||||
|
The core concept is, to have instances of dataclasses that hold all values. On programm start the values are just overridden by those in the file.
|
||||||
|
|
||||||
|
## Dataclass Structure
|
||||||
|
|
||||||
|
You have one [File](#file) class, that contains a list of [Section](#section) classes.
|
||||||
|
Every [Section](#section) class contains a list of [SectionElement](#section-elements) classes.
|
||||||
|
|
||||||
|
# Classes
|
||||||
|
|
||||||
|
## File
|
||||||
|
|
||||||
|
`File` classes have one name, with whom the path will be generated:
|
||||||
|
|
||||||
|
```
|
||||||
|
{CONFIG_DIR}/{file_name}.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
I also pass in the config direcory in the constructor, such that the module can be pretty independently used. Though it's default value is the default config director from `utils.path_manager`.
|
||||||
|
|
||||||
|
|
||||||
|
They contain a list of [ConfigElement](#config-elements)s, arguably the most important ones.
|
||||||
|
|
||||||
|
## Config Elements
|
||||||
|
|
||||||
|
# Config Syntax
|
||||||
|
|
||||||
|
- every line is stripped from all whitespaces at the beginning and end
|
||||||
|
|
||||||
|
```
|
||||||
|
# a comment
|
||||||
|
|
||||||
|
config_name=some_value
|
||||||
|
|
||||||
|
# list
|
||||||
|
[config_name.list.start]
|
||||||
|
config_name=one list item
|
||||||
|
config_name=another list item
|
||||||
|
[config_name.list.end]
|
||||||
|
|
||||||
|
# dict
|
||||||
|
[config_name.dict.start]
|
||||||
|
one_key=one value item
|
||||||
|
another_key=another value item
|
||||||
|
[config_name.dict.end]
|
||||||
|
```
|
||||||
|
|
||||||
|
- empty lines will be ignored
|
||||||
|
- If `#` is at the beginning of the line, it will be ignored
|
||||||
|
- if there is neither a `\[.*\]` or a `=` in a line, it will raise a warning, but will be ignored
|
0
src/music_kraken/_settings/__init__.py
Normal file
0
src/music_kraken/_settings/__init__.py
Normal file
127
src/music_kraken/_settings/base_models.py
Normal file
127
src/music_kraken/_settings/base_models.py
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
from typing import Optional, List, Union, Dict
|
||||||
|
from collections.abc import Iterable
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import toml
|
||||||
|
|
||||||
|
|
||||||
|
def comment_string(uncommented_string: str) -> str:
|
||||||
|
_fragments = uncommented_string.split("\n")
|
||||||
|
_fragments = ["# " + frag for frag in _fragments]
|
||||||
|
return "\n".join(_fragments)
|
||||||
|
|
||||||
|
|
||||||
|
class Comment:
|
||||||
|
def __init__(self, value: str) -> None:
|
||||||
|
self.value: str = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def uncommented(self) -> str:
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def commented(self) -> str:
|
||||||
|
return comment_string(self.value)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.commented
|
||||||
|
|
||||||
|
|
||||||
|
class Attribute:
|
||||||
|
def __init__(self, data: dict, comment: Optional[str] = None) -> None:
|
||||||
|
self.data: dict = data
|
||||||
|
self.comment: Optional[Comment] = None if comment is None else Comment(
|
||||||
|
comment)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def toml_string(self) -> str:
|
||||||
|
_data_string = toml.dumps(self.data)
|
||||||
|
components: List[str] = [_data_string]
|
||||||
|
|
||||||
|
if self.comment is not None:
|
||||||
|
components.append(self.comment.commented)
|
||||||
|
|
||||||
|
return "\n".join(components)
|
||||||
|
|
||||||
|
def __setitem__(self, key: str, value):
|
||||||
|
if key not in self.data:
|
||||||
|
self.data[key] = value
|
||||||
|
|
||||||
|
if isinstance(self.data[key], dict) and isinstance(value, dict):
|
||||||
|
self.data[key].update(value)
|
||||||
|
|
||||||
|
self.data[key] = value
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFile:
|
||||||
|
def __init__(self, config_file: Path, data: List[Union[Attribute, Comment]]) -> None:
|
||||||
|
self.config_file: Path = config_file
|
||||||
|
|
||||||
|
self.unknown_attribute: Attribute = Attribute(
|
||||||
|
{}, "This is the attribute is for all unknown attributes.")
|
||||||
|
|
||||||
|
self._data: List[Union[Attribute, Comment]] = data
|
||||||
|
self._key_attribute_map: Dict[str, Attribute] = {}
|
||||||
|
for attribute in self._data:
|
||||||
|
if isinstance(attribute, Comment):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for key in attribute.data:
|
||||||
|
self._key_attribute_map[key] = attribute
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
self.update(toml.load(self.config_file.open("r"), encoding="utf-8"))
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
with self.config_file.open("w", encoding="utf-8") as config_file:
|
||||||
|
config_file.write(self.toml_string)
|
||||||
|
|
||||||
|
def update(self, data: dict):
|
||||||
|
for key, value in data.items():
|
||||||
|
if key not in self._key_attribute_map:
|
||||||
|
self._key_attribute_map[key] = self.unknown_attribute
|
||||||
|
self.unknown_attribute[key] = value
|
||||||
|
continue
|
||||||
|
|
||||||
|
self._key_attribute_map[key][key] = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def toml_string(self) -> str:
|
||||||
|
components: List[str] = []
|
||||||
|
for attribute in self._data:
|
||||||
|
if isinstance(attribute, Attribute):
|
||||||
|
components.append(attribute.toml_string)
|
||||||
|
|
||||||
|
components.append(self.unknown_attribute.toml_string)
|
||||||
|
|
||||||
|
return "\n\n".join(components)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.toml_string
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
settings = ConfigFile(Path("/home/lars/.config/music-kraken/music-kraken.toml"), [
|
||||||
|
Attribute({
|
||||||
|
"happy_message": [
|
||||||
|
"Support the artist.",
|
||||||
|
"Star Me: https://github.com/HeIIow2/music-downloader",
|
||||||
|
"🏳️⚧️🏳️⚧️ Trans rights are human rights. 🏳️⚧️🏳️⚧️",
|
||||||
|
"🏳️⚧️🏳️⚧️ Trans women are women, trans men are men, and enbies are enbies. 🏳️⚧️🏳️⚧️",
|
||||||
|
"🏴☠️🏴☠️ Unite under one flag, fck borders. 🏴☠️🏴☠️",
|
||||||
|
"Join my Matrix Space: https://matrix.to/#/#music-kraken:matrix.org",
|
||||||
|
"Gotta love the BPJM ;-;",
|
||||||
|
"🏳️⚧️🏳️⚧️ Protect trans youth. 🏳️⚧️🏳️⚧️",
|
||||||
|
"Nonstop Progressive Marxism.",
|
||||||
|
],
|
||||||
|
"bitrate": 66.6
|
||||||
|
},
|
||||||
|
comment="this is a test section"
|
||||||
|
),
|
||||||
|
Attribute({
|
||||||
|
"# hihi": "byebey"
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
print(settings)
|
||||||
|
settings.dump()
|
@ -1,6 +1,8 @@
|
|||||||
from dynaconf import Dynaconf
|
from dynaconf import Dynaconf
|
||||||
|
from dynaconf import settings
|
||||||
|
from dynaconf.utils import object_merge
|
||||||
|
|
||||||
from .path_manager import LOCATIONS
|
# from .path_manager import LOCATIONS
|
||||||
|
|
||||||
"""
|
"""
|
||||||
https://www.dynaconf.com/settings_files/
|
https://www.dynaconf.com/settings_files/
|
||||||
@ -12,6 +14,27 @@ The concept is that I package a config file, with this programm, and then load i
|
|||||||
Then I check if there is a config file at the LOCATIONS.CONFIG_FILE, and if yes they get merged
|
Then I check if there is a config file at the LOCATIONS.CONFIG_FILE, and if yes they get merged
|
||||||
"""
|
"""
|
||||||
|
|
||||||
settings = Dynaconf(
|
settings.happy_message = [
|
||||||
settings_files=[str(LOCATIONS.CONFIG_FILE)],
|
"Support the artist.",
|
||||||
|
"Star Me: https://github.com/HeIIow2/music-downloader",
|
||||||
|
"🏳️⚧️🏳️⚧️ Trans rights are human rights. 🏳️⚧️🏳️⚧️",
|
||||||
|
"🏳️⚧️🏳️⚧️ Trans women are women, trans men are men, and enbies are enbies. 🏳️⚧️🏳️⚧️",
|
||||||
|
"🏴☠️🏴☠️ Unite under one flag, fck borders. 🏴☠️🏴☠️",
|
||||||
|
"Join my Matrix Space: https://matrix.to/#/#music-kraken:matrix.org",
|
||||||
|
"Gotta love the BPJM ;-;",
|
||||||
|
"🏳️⚧️🏳️⚧️ Protect trans youth. 🏳️⚧️🏳️⚧️",
|
||||||
|
"Nonstop Progressive Marxism.",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
dynacont_object = Dynaconf(
|
||||||
|
settings_files=[str(LOCATIONS.CONFIG_FILE)]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Settings:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user