2023-09-12 11:56:40 +00:00
|
|
|
from typing import Any, Tuple, Union, List
|
2023-09-10 14:27:09 +00:00
|
|
|
from pathlib import Path
|
2023-04-14 15:01:32 +00:00
|
|
|
import logging
|
2023-09-12 11:56:40 +00:00
|
|
|
from datetime import datetime
|
2023-04-13 21:45:50 +00:00
|
|
|
|
2023-09-10 14:27:09 +00:00
|
|
|
import toml
|
2023-04-15 15:17:33 +00:00
|
|
|
|
2023-09-10 14:27:09 +00:00
|
|
|
from .attributes.attribute import Attribute, Description, EmptyLine
|
2023-04-14 09:22:47 +00:00
|
|
|
|
2023-04-13 21:45:50 +00:00
|
|
|
|
2023-09-10 14:54:06 +00:00
|
|
|
class ConfigDict(dict):
|
|
|
|
def __init__(self, config_reference: "Config", *args, **kwargs):
|
|
|
|
self.config_reference: Config = config_reference
|
|
|
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
2023-09-12 10:33:39 +00:00
|
|
|
def __getitem__(self, __name: str) -> Any:
|
|
|
|
return super().__getitem__(__name)
|
2023-09-10 14:54:06 +00:00
|
|
|
|
2023-09-10 17:00:51 +00:00
|
|
|
def __setitem__(self, __key: Any, __value: Any, from_attribute: bool = False, is_parsed: bool = False) -> None:
|
2023-09-10 15:27:07 +00:00
|
|
|
if not from_attribute:
|
|
|
|
attribute: Attribute = self.config_reference.attribute_map[__key]
|
2023-09-10 17:00:51 +00:00
|
|
|
if is_parsed:
|
|
|
|
attribute.value = __value
|
|
|
|
else:
|
|
|
|
attribute.parse(__value)
|
2023-09-10 15:27:07 +00:00
|
|
|
self.config_reference.write()
|
2023-09-10 14:54:06 +00:00
|
|
|
|
2023-09-10 15:27:07 +00:00
|
|
|
__value = attribute.value
|
|
|
|
|
|
|
|
return super().__setitem__(__key, __value)
|
2023-09-10 14:54:06 +00:00
|
|
|
|
|
|
|
|
2023-04-14 15:01:32 +00:00
|
|
|
class Config:
|
2024-01-22 17:36:16 +00:00
|
|
|
def __init__(self, component_list: Tuple[Union[Attribute, Description, EmptyLine], ...], config_file: Path) -> None:
|
2023-09-10 14:27:09 +00:00
|
|
|
self.config_file: Path = config_file
|
2023-04-14 16:28:33 +00:00
|
|
|
|
2023-09-12 11:56:40 +00:00
|
|
|
self.component_list: List[Union[Attribute, Description, EmptyLine]] = [
|
|
|
|
Description(f"""IMPORTANT: If you modify this file, the changes for the actual setting, will be kept as is.
|
|
|
|
The changes you make to the comments, will be discarded, next time you run music-kraken. Have fun!
|
|
|
|
|
|
|
|
Latest reset: {datetime.now()}
|
|
|
|
|
|
|
|
_____
|
|
|
|
/ ____|
|
|
|
|
| | __ __ _ _ _
|
|
|
|
| | |_ | / _` || | | |
|
|
|
|
| |__| || (_| || |_| |
|
|
|
|
\_____| \__,_| \__, |
|
|
|
|
__/ |
|
|
|
|
|___/
|
|
|
|
""")]
|
|
|
|
|
|
|
|
self.component_list.extend(component_list)
|
2023-09-10 15:27:07 +00:00
|
|
|
self.loaded_settings: ConfigDict = ConfigDict(self)
|
2023-04-15 09:54:17 +00:00
|
|
|
|
2023-09-10 14:54:06 +00:00
|
|
|
self.attribute_map = {}
|
|
|
|
for component in self.component_list:
|
|
|
|
if not isinstance(component, Attribute):
|
|
|
|
continue
|
|
|
|
|
2023-09-10 15:27:07 +00:00
|
|
|
component.initialize_from_config(self.loaded_settings)
|
2023-09-10 14:54:06 +00:00
|
|
|
self.attribute_map[component.name] = component
|
|
|
|
|
2023-04-14 10:40:52 +00:00
|
|
|
@property
|
2023-09-10 14:27:09 +00:00
|
|
|
def toml_string(self):
|
2023-09-10 17:00:51 +00:00
|
|
|
return "\n".join(component.toml_string for component in self.component_list)
|
2023-04-14 10:40:52 +00:00
|
|
|
|
2023-09-10 14:27:09 +00:00
|
|
|
def write(self):
|
|
|
|
with self.config_file.open("w") as conf_file:
|
|
|
|
conf_file.write(self.toml_string)
|
2023-04-14 16:28:33 +00:00
|
|
|
|
2023-09-10 14:27:09 +00:00
|
|
|
def read(self):
|
|
|
|
if not self.config_file.is_file():
|
|
|
|
logging.info(f"Config file at '{self.config_file}' doesn't exist => generating")
|
|
|
|
self.write()
|
2023-04-14 16:28:33 +00:00
|
|
|
return
|
2023-09-10 14:27:09 +00:00
|
|
|
|
|
|
|
toml_data = {}
|
|
|
|
with self.config_file.open("r") as conf_file:
|
|
|
|
toml_data = toml.load(conf_file)
|
|
|
|
|
|
|
|
for component in self.component_list:
|
|
|
|
if isinstance(component, Attribute):
|
2023-09-10 15:27:07 +00:00
|
|
|
component.load_toml(toml_data)
|