Files
TwitchDropsMiner/settings.py

103 lines
2.6 KiB
Python

from __future__ import annotations
import json
from enum import Enum
from pathlib import Path
from typing import Any, TypedDict, TYPE_CHECKING
from constants import JsonType, SETTINGS_PATH
if TYPE_CHECKING:
from main import ParsedArgs
PATH = Path(SETTINGS_PATH)
class SettingsFile(TypedDict):
autostart: bool
exclude: set[str]
priority: list[str]
priority_only: bool
autostart_tray: bool
serialize_env: dict[str, type] = {
"set": set,
}
default_settings: SettingsFile = {
"priority": [],
"exclude": set(),
"autostart": False,
"priority_only": True,
"autostart_tray": False,
}
def serialize(obj: Any) -> Any:
if isinstance(obj, (set, Enum)):
if isinstance(obj, set):
d = list(obj)
elif isinstance(obj, Enum):
d = obj.value
return {
"__type": type(obj).__name__,
"data": d,
}
raise TypeError(obj)
def deserialize(obj: JsonType) -> Any:
if "__type" in obj:
t = eval(obj["__type"], None, serialize_env)
return t(obj["data"])
return obj
class Settings:
# from args
log: bool
tray: bool
no_run_check: bool
# args properties
debug_ws: int
debug_gql: int
logging_level: int
# from settings file
autostart: bool
exclude: set[str]
priority: list[str]
priority_only: bool
autostart_tray: bool
def __init__(self, args: ParsedArgs):
self._settings: SettingsFile = default_settings.copy()
if PATH.exists():
with open(PATH, 'r') as file:
self._settings.update(json.load(file, object_hook=deserialize))
self._args: ParsedArgs = args
# default logic of reading settings is to check args first, then the settings file
def __getattr__(self, name: str, /) -> Any:
if hasattr(self._args, name):
return getattr(self._args, name)
elif name in self._settings:
return self._settings[name] # type: ignore[misc]
return getattr(super(), name)
def __setattr__(self, name: str, value: Any, /) -> None:
if name in ("_settings", "_args"):
# passthrough
return super().__setattr__(name, value)
elif name in self._settings:
self._settings[name] = value # type: ignore[misc]
return
raise TypeError(f"{name} is missing a custom setter")
def __delattr__(self, name: str, /) -> None:
raise RuntimeError("settings can't be deleted")
def save(self) -> None:
with open(PATH, 'w') as file:
json.dump(self._settings, file, default=serialize, sort_keys=True, indent=4)