music-kraken-core/music_kraken/utils/config/attributes/attribute.py

133 lines
3.5 KiB
Python
Raw Normal View History

2023-08-10 21:01:16 +00:00
import re
2023-09-10 14:27:09 +00:00
from typing import Optional, List, Union, Iterable, Callable
from dataclasses import dataclass
import logging
import toml
2023-09-10 17:00:51 +00:00
from copy import deepcopy, copy
from urllib.parse import urlparse, urlunparse, ParseResult
2023-08-10 21:01:16 +00:00
from ...exception.config import SettingValueError
from ..utils import comment
2023-09-10 14:27:09 +00:00
LOGGER = logging.getLogger("config")
COMMENT_PREFIX = "#"
def comment_string(uncommented: str) -> str:
unprocessed_lines = uncommented.split("\n")
processed_lines: List[str] = []
for line in unprocessed_lines:
if line.startswith(COMMENT_PREFIX) or line == "":
processed_lines.append(line)
continue
line = COMMENT_PREFIX + " " + line
processed_lines.append(line)
return "\n".join(processed_lines)
@dataclass
2023-08-10 21:01:16 +00:00
class Description:
2023-09-10 14:27:09 +00:00
description: str
2023-08-10 21:01:16 +00:00
@property
2023-09-10 14:27:09 +00:00
def toml_string(self):
return comment_string(self.description)
2023-08-10 21:01:16 +00:00
2023-09-10 14:27:09 +00:00
class EmptyLine(Description):
def __init__(self):
self.description = ""
2023-08-10 21:01:16 +00:00
2023-09-10 14:27:09 +00:00
class Attribute:
def __init__(
self,
name: str,
default_value: any,
description: Optional[str] = None,
):
2023-08-10 21:01:16 +00:00
self.name = name
2023-09-10 17:00:51 +00:00
self.value = self._recursive_parse_object(default_value, self.parse_simple_value)
2023-09-10 14:27:09 +00:00
self.description: Optional[str] = description
2023-09-10 15:27:07 +00:00
self.loaded_settings: dict = None
def initialize_from_config(self, loaded_settings: dict):
self.loaded_settings = loaded_settings
2023-09-10 17:00:51 +00:00
self.loaded_settings.__setitem__(self.name, self.value, True)
2023-09-10 14:27:09 +00:00
def unparse_simple_value(self, value: any) -> any:
return value
def parse_simple_value(self, value: any) -> any:
return value
2023-08-10 21:01:16 +00:00
2023-09-10 14:27:09 +00:00
def _recursive_parse_object(self, __object, callback: Callable):
2023-09-10 17:00:51 +00:00
__object = copy(__object)
2023-09-10 14:27:09 +00:00
if isinstance(__object, dict):
for key, value in __object.items():
__object[key] = self._recursive_parse_object(value, callback)
return __object
2023-08-10 21:01:16 +00:00
2023-09-10 17:00:51 +00:00
if isinstance(__object, list) or (isinstance(__object, tuple) and not isinstance(__object, ParseResult)):
2023-09-10 14:27:09 +00:00
for i, item in enumerate(__object):
__object[i] = self._recursive_parse_object(item, callback)
return __object
return callback(__object)
2023-09-10 17:00:51 +00:00
def parse(self, unparsed_value):
self.value = self._recursive_parse_object(unparsed_value, self.parse_simple_value)
return self.value
def unparse(self, parsed_value):
return self._recursive_parse_object(parsed_value, self.unparse_simple_value)
2023-09-10 14:27:09 +00:00
2023-09-10 15:27:07 +00:00
def load_toml(self, loaded_toml: dict) -> bool:
2023-09-10 14:27:09 +00:00
"""
returns true if succesfull
"""
if self.name not in loaded_toml:
LOGGER.warning(f"No setting by the name {self.name} found in the settings file.")
2023-09-10 15:27:07 +00:00
self.loaded_settings.__setitem__(self.name, self.value, True)
2023-09-10 14:27:09 +00:00
return
try:
2023-09-10 17:00:51 +00:00
self.parse(loaded_toml[self.name])
2023-09-10 14:27:09 +00:00
except SettingValueError as settings_error:
logging.warning(settings_error)
return False
2023-09-10 17:00:51 +00:00
2023-09-10 15:27:07 +00:00
self.loaded_settings.__setitem__(self.name, self.value, True)
2023-09-10 14:27:09 +00:00
return True
2023-08-10 21:01:16 +00:00
@property
2023-09-10 14:27:09 +00:00
def toml_string(self) -> str:
string = ""
if self.description is not None:
string += comment(self.description) + "\n"
2023-09-10 17:00:51 +00:00
string += toml.dumps({self.name: self.unparse(self.value)})
2023-08-10 21:01:16 +00:00
2023-09-10 17:00:51 +00:00
# print(string)
2023-09-10 14:27:09 +00:00
return string
2023-08-10 21:01:16 +00:00
2023-09-10 14:27:09 +00:00
def __str__(self):
return f"{self.description}\n{self.name}={self.value}"
2023-08-10 21:01:16 +00:00