-
-
Notifications
You must be signed in to change notification settings - Fork 173
/
settings.py
92 lines (75 loc) · 2.52 KB
/
settings.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from __future__ import annotations
from typing import Any, TypedDict, TYPE_CHECKING
from yarl import URL
from utils import json_load, json_save
from constants import SETTINGS_PATH, DEFAULT_LANG, PriorityMode
if TYPE_CHECKING:
from main import ParsedArgs
class SettingsFile(TypedDict):
proxy: URL
language: str
exclude: set[str]
priority: list[str]
autostart_tray: bool
connection_quality: int
tray_notifications: bool
priority_mode: PriorityMode
default_settings: SettingsFile = {
"proxy": URL(),
"priority": [],
"exclude": set(),
"autostart_tray": False,
"connection_quality": 1,
"language": DEFAULT_LANG,
"tray_notifications": True,
"priority_mode": PriorityMode.PRIORITY_ONLY,
}
class Settings:
# from args
log: bool
tray: bool
dump: bool
# args properties
debug_ws: int
debug_gql: int
logging_level: int
# from settings file
proxy: URL
language: str
exclude: set[str]
priority: list[str]
autostart_tray: bool
connection_quality: int
tray_notifications: bool
priority_mode: PriorityMode
PASSTHROUGH = ("_settings", "_args", "_altered")
def __init__(self, args: ParsedArgs):
self._settings: SettingsFile = json_load(SETTINGS_PATH, default_settings)
self._args: ParsedArgs = args
self._altered: bool = False
# default logic of reading settings is to check args first, then the settings file
def __getattr__(self, name: str, /) -> Any:
if name in self.PASSTHROUGH:
# passthrough
return getattr(super(), name)
elif hasattr(self._args, name):
return getattr(self._args, name)
elif name in self._settings:
return self._settings[name] # type: ignore[literal-required]
return getattr(super(), name)
def __setattr__(self, name: str, value: Any, /) -> None:
if name in self.PASSTHROUGH:
# passthrough
return super().__setattr__(name, value)
elif name in self._settings:
self._settings[name] = value # type: ignore[literal-required]
self._altered = True
return
raise TypeError(f"{name} is missing a custom setter")
def __delattr__(self, name: str, /) -> None:
raise RuntimeError("settings can't be deleted")
def alter(self) -> None:
self._altered = True
def save(self, *, force: bool = False) -> None:
if self._altered or force:
json_save(SETTINGS_PATH, self._settings, sort=True)