toot/toot/settings.py

62 wiersze
1.4 KiB
Python

2023-06-24 15:29:11 +00:00
from functools import lru_cache
from os.path import exists, join
from tomlkit import parse
from toot import get_config_dir
2023-07-07 10:17:36 +00:00
from typing import Optional, Type, TypeVar
2023-06-24 15:29:11 +00:00
2023-06-28 12:55:28 +00:00
DISABLE_SETTINGS = False
2023-06-24 15:29:11 +00:00
TOOT_SETTINGS_FILE_NAME = "settings.toml"
def get_settings_path():
return join(get_config_dir(), TOOT_SETTINGS_FILE_NAME)
2023-12-05 11:00:45 +00:00
def _load_settings() -> dict:
2023-06-28 12:55:28 +00:00
# Used for testing without config file
if DISABLE_SETTINGS:
return {}
path = get_settings_path()
if not exists(path):
2023-06-24 15:29:11 +00:00
return {}
with open(path) as f:
2023-06-24 15:29:11 +00:00
return parse(f.read())
@lru_cache(maxsize=None)
def get_settings():
2023-12-05 11:00:45 +00:00
return _load_settings()
2023-06-24 15:29:11 +00:00
2023-07-07 10:17:36 +00:00
T = TypeVar("T")
def get_setting(key: str, type: Type[T], default: Optional[T] = None) -> Optional[T]:
2023-06-24 15:29:11 +00:00
"""
Get a setting value. The key should be a dot-separated string,
e.g. "commands.post.editor" which will correspond to the "editor" setting
inside the `[commands.post]` section.
"""
settings = get_settings()
return _get_setting(settings, key.split("."), type, default)
def _get_setting(dct, keys, type: Type, default=None):
if len(keys) == 0:
if isinstance(dct, type):
return dct
else:
2023-06-28 11:56:59 +00:00
# TODO: warn? cast? both?
2023-06-24 15:29:11 +00:00
return default
key = keys[0]
if isinstance(dct, dict) and key in dct:
return _get_setting(dct[key], keys[1:], type, default)
return default