Implement settings and saving them to the settings file
This commit is contained in:
1 parent
82b999995f
commit
5a3a540b45
7 files changed
+741
-179
No files matched your search
+102
@@ -0,0 +1,102 @@
|
||||
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)
|
||||
Reference in new issue
Block a user