mirror of https://github.com/LedFx/LedFx.git
134 lines
4.3 KiB
Python
134 lines
4.3 KiB
Python
import voluptuous as vol
|
|
import logging
|
|
import yaml
|
|
import sys
|
|
import os
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
CONFIG_DIRECTORY = ".ledfx"
|
|
CONFIG_FILE_NAME = "config.yaml"
|
|
DEFAULT_PRESETS_FILE_NAME = "default_presets.yaml"
|
|
|
|
CORE_CONFIG_SCHEMA = vol.Schema(
|
|
{
|
|
vol.Optional("host", default="0.0.0.0"): str,
|
|
vol.Optional("port", default=8888): int,
|
|
vol.Optional("dev_mode", default=False): bool,
|
|
vol.Optional("max_workers", default=10): int,
|
|
vol.Optional("devices", default=[]): list,
|
|
vol.Optional("default_presets", default={}): dict,
|
|
vol.Optional("custom_presets", default={}): dict,
|
|
vol.Optional("scenes", default={}): dict,
|
|
vol.Optional("fade", default=1.0): float,
|
|
},
|
|
extra=vol.ALLOW_EXTRA,
|
|
)
|
|
|
|
|
|
def get_default_config_directory() -> str:
|
|
"""Get the default configuration directory"""
|
|
|
|
base_dir = (
|
|
os.getenv("APPDATA") if os.name == "nt" else os.path.expanduser("~")
|
|
)
|
|
return os.path.join(base_dir, CONFIG_DIRECTORY)
|
|
|
|
|
|
def get_config_file(config_dir: str) -> str:
|
|
"""Finds a supported configuration fill in the provided directory"""
|
|
|
|
config_path = os.path.join(config_dir, CONFIG_FILE_NAME)
|
|
return config_path if os.path.isfile(config_path) else None
|
|
|
|
|
|
def create_default_config(config_dir: str) -> str:
|
|
"""Creates a default configuration in the provided directory"""
|
|
|
|
config_path = os.path.join(config_dir, CONFIG_FILE_NAME)
|
|
try:
|
|
with open(config_path, "wt") as file:
|
|
yaml.dump(CORE_CONFIG_SCHEMA({}), file, default_flow_style=False)
|
|
return config_path
|
|
|
|
except IOError:
|
|
print(
|
|
("Unable to create default configuration file {}").format(
|
|
config_path
|
|
)
|
|
)
|
|
return None
|
|
|
|
|
|
def ensure_config_file(config_dir: str) -> str:
|
|
"""Checks if a config file exists, and otherwise creates one"""
|
|
|
|
ensure_config_directory(config_dir)
|
|
config_path = get_config_file(config_dir)
|
|
if config_path is None:
|
|
config_path = create_default_config(config_dir)
|
|
|
|
return config_path
|
|
|
|
|
|
def ensure_config_directory(config_dir: str) -> None:
|
|
"""Validate that the config directory is valid."""
|
|
|
|
# If an explicit path is provided simply check if it exist and failfast
|
|
# if it doesn't. Otherwise, if we have the default directory attempt to
|
|
# create the file
|
|
if not os.path.isdir(config_dir):
|
|
if config_dir != get_default_config_directory():
|
|
print(
|
|
("Error: Invalid configuration directory {}").format(
|
|
config_dir
|
|
)
|
|
)
|
|
sys.exit(1)
|
|
|
|
try:
|
|
os.mkdir(config_dir)
|
|
except OSError:
|
|
print(
|
|
("Error: Unable to create configuration directory {}").format(
|
|
config_dir
|
|
)
|
|
)
|
|
sys.exit(1)
|
|
|
|
|
|
def load_config(config_dir: str) -> dict:
|
|
"""Validates and loads the configuration file in the provided directory"""
|
|
|
|
config_file = ensure_config_file(config_dir)
|
|
print(("Loading configuration file from {}").format(config_dir))
|
|
with open(config_file, "rt") as file:
|
|
config_yaml = yaml.safe_load(file)
|
|
if config_yaml is None:
|
|
config_yaml = {}
|
|
return CORE_CONFIG_SCHEMA(config_yaml)
|
|
|
|
|
|
def load_default_presets() -> dict:
|
|
ledfx_dir = os.path.dirname(os.path.realpath(__file__))
|
|
default_presets_path = os.path.join(ledfx_dir, DEFAULT_PRESETS_FILE_NAME)
|
|
print("Loading default presets from {}".format(ledfx_dir))
|
|
if not os.path.isfile(default_presets_path):
|
|
print("Failed to load {}".format(DEFAULT_PRESETS_FILE_NAME))
|
|
with open(default_presets_path, "rt") as file:
|
|
return yaml.safe_load(file)
|
|
|
|
|
|
def save_config(config: dict, config_dir: str) -> None:
|
|
"""Saves the configuration to the provided directory"""
|
|
|
|
config_file = ensure_config_file(config_dir)
|
|
_LOGGER.info(("Saving configuration file to {}").format(config_dir))
|
|
# prevent defaults being saved to config.yaml by creating a copy (python
|
|
# no pass by value)
|
|
config_view = dict(config)
|
|
if "default_presets" in config_view.keys():
|
|
del config_view["default_presets"]
|
|
with open(config_file, "w") as file:
|
|
yaml.dump(config_view, file, default_flow_style=False)
|