68 lines
2.3 KiB
Python
68 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
import logging
|
|
import os.path
|
|
|
|
import yaml
|
|
|
|
_cached_config: Config | None = None
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class Config:
|
|
_source_filename: str
|
|
controllers: list[str]
|
|
server_names: list[str]
|
|
comm_secret: str
|
|
cookie_secret: str
|
|
venue_info_url: str | None
|
|
session_timeout: int # in seconds
|
|
api_port: int
|
|
controller_port: int
|
|
database_file: str # empty str: disable database
|
|
custom: str
|
|
debug: bool
|
|
|
|
@staticmethod
|
|
def load_default_once(filename: str | None = None) -> Config:
|
|
global _cached_config
|
|
if not _cached_config:
|
|
_cached_config = Config.load(filename)
|
|
elif not filename is None and filename != _cached_config._source_filename:
|
|
raise RuntimeError(
|
|
f"Already loaded different config from {_cached_config._source_filename!r} instead of {filename!r}",
|
|
)
|
|
return _cached_config
|
|
|
|
@staticmethod
|
|
def load(filename: str | None = None) -> Config:
|
|
if filename is None:
|
|
for name in ("capport.yaml", "/etc/capport.yaml"):
|
|
if os.path.exists(name):
|
|
return Config.load(name)
|
|
raise RuntimeError("Missing config file")
|
|
with open(filename) as f:
|
|
data = yaml.safe_load(f)
|
|
if not isinstance(data, dict):
|
|
raise RuntimeError(f"Invalid yaml config data, expected dict: {data!r}")
|
|
controllers = list(map(str, data.pop("controllers")))
|
|
config = Config(
|
|
_source_filename=filename,
|
|
controllers=controllers,
|
|
server_names=data.pop("server-names", []),
|
|
comm_secret=str(data.pop("comm-secret")),
|
|
cookie_secret=str(data.pop("cookie-secret")),
|
|
venue_info_url=str(data.pop("venue-info-url")),
|
|
session_timeout=data.pop("session-timeout", 3600),
|
|
api_port=data.pop("api-port", 8000),
|
|
controller_port=data.pop("controller-port", 5000),
|
|
database_file=str(data.pop("database-file", "capport.state")),
|
|
custom=str(data.pop("custom", "custom")),
|
|
debug=data.pop("debug", False),
|
|
)
|
|
if data:
|
|
_logger.error(f"Unknown config elements: {list(data.keys())}")
|
|
return config
|