167 lines
4.9 KiB
Python
167 lines
4.9 KiB
Python
from pathlib import Path
|
|
import json
|
|
from typing import Dict, Optional, List
|
|
import os
|
|
import logging
|
|
import toml
|
|
import random
|
|
import requests
|
|
|
|
from .static import get_config_file
|
|
|
|
mommy_logger = logging.getLogger("mommy")
|
|
serious_logger = logging.getLogger("serious")
|
|
|
|
PREFIX = "MOMMY"
|
|
|
|
RESPONSES_URL = "https://raw.githubusercontent.com/Gankra/cargo-mommy/refs/heads/main/responses.json"
|
|
RESPONSES_FILE = Path(__file__).parent / "responses.json"
|
|
ADDITIONAL_ENV_VARS = {
|
|
"pronoun": "PRONOUNS",
|
|
"role": "ROLES",
|
|
"emote": "EMOTES",
|
|
"mood": "MOODS",
|
|
}
|
|
|
|
|
|
|
|
def _load_config_file(config_file: Path) -> dict:
|
|
with config_file.open("r") as f:
|
|
data = toml.load(f)
|
|
|
|
result = {}
|
|
for key, value in data.items():
|
|
if isinstance(value, str):
|
|
result[key] = [value]
|
|
else:
|
|
result[key] = value
|
|
|
|
return result
|
|
|
|
|
|
ADDITIONAL_PROGRAM_PREFIXES = [
|
|
"cargo", # only as fallback if user already configured cargo
|
|
]
|
|
|
|
def _get_env_var_names(name: str):
|
|
BASE = PREFIX + "_" + name.upper()
|
|
yield "PYTHON_" + BASE
|
|
yield BASE
|
|
for a in ADDITIONAL_PROGRAM_PREFIXES:
|
|
yield a + "_" + BASE
|
|
|
|
def _get_env_value(name: str) -> Optional[str]:
|
|
if name in ADDITIONAL_ENV_VARS:
|
|
for key in _get_env_var_names(ADDITIONAL_ENV_VARS[name]):
|
|
val = os.environ.get(key)
|
|
if val is not None:
|
|
return val
|
|
|
|
for key in _get_env_var_names(name):
|
|
val = os.environ.get(key)
|
|
if val is not None:
|
|
return val
|
|
|
|
|
|
def compile_config(disable_requests: bool = False) -> dict:
|
|
global RESPONSES_FILE, RESPONSES_URL
|
|
|
|
data = json.loads(RESPONSES_FILE.read_text())
|
|
|
|
if not disable_requests:
|
|
mommy_logger.info("mommy downloads newest responses for her girl~ %s", RESPONSES_URL)
|
|
serious_logger.info("downloading cargo mommy responses: %s", RESPONSES_URL)
|
|
try:
|
|
r = requests.get(RESPONSES_URL)
|
|
data = r.json()
|
|
except requests.exceptions.ConnectionError:
|
|
mommy_logger.info("mommy couldn't fetch the url~")
|
|
serious_logger.info("couldnt fetch the url")
|
|
|
|
config_definition: Dict[str, dict] = data["vars"]
|
|
mood_definitions: Dict[str, dict] = data["moods"]
|
|
|
|
# environment variables for compatibility with cargo mommy
|
|
# fill ADDITIONAL_ENV_VARS with the "env_key" values
|
|
for key, conf in config_definition.items():
|
|
if "env_key" in conf:
|
|
ADDITIONAL_ENV_VARS[key] = conf["env_key"]
|
|
|
|
# set config to the default values
|
|
config: Dict[str, List[str]] = {}
|
|
for key, conf in config_definition.items():
|
|
config[key] = conf["defaults"]
|
|
|
|
# load config file
|
|
config_file = get_config_file()
|
|
if config_file is not None:
|
|
c = _load_config_file(config_file)
|
|
serious_logger.debug(
|
|
"config at %s:\n%s\n",
|
|
config_file,
|
|
json.dumps(c, indent=4)
|
|
)
|
|
|
|
config["mood"] = c.get("moods", config["mood"])
|
|
c_vars: dict = c.get("vars", {})
|
|
# validate the config var values
|
|
for key, val in c_vars.items():
|
|
if not isinstance(val, list):
|
|
mommy_logger.error("mommy needs the value of %s to be a list~", key)
|
|
serious_logger.error("the value of %s is not a list", key)
|
|
exit(1)
|
|
config.update(c_vars)
|
|
|
|
# fill config with env
|
|
for key, conf in config_definition.items():
|
|
val = _get_env_value(key)
|
|
if val is not None:
|
|
config[key] = val.split("/")
|
|
|
|
# validate empty variables
|
|
empty_values = []
|
|
for key, value in config.items():
|
|
if len(value) == 0:
|
|
empty_values.append(key)
|
|
if len(empty_values) > 0:
|
|
empty_values_sting = ", ".join(empty_values)
|
|
mommy_logger.error(
|
|
"mommy is very displeased that you didn't config the key(s) %s",
|
|
empty_values_sting,
|
|
)
|
|
serious_logger.error(
|
|
"the following keys have empty values and need to be configured: %s",
|
|
empty_values_sting
|
|
)
|
|
exit(1)
|
|
|
|
# validate moods
|
|
for mood in config["mood"]:
|
|
if mood not in mood_definitions:
|
|
supported_moods_str = ", ".join(mood_definitions.keys())
|
|
mommy_logger.error(
|
|
"%s doesn't know how to feel %s... %s moods are %s",
|
|
random.choice(config['role']),
|
|
mood,
|
|
random.choice(config['pronoun']),
|
|
supported_moods_str,
|
|
)
|
|
serious_logger.error(
|
|
"mood '%s' doesn't exist. moods are %s",
|
|
mood,
|
|
supported_moods_str,
|
|
)
|
|
exit(1)
|
|
|
|
# compile
|
|
compiled = {}
|
|
compiled_moods = compiled["moods"] = {}
|
|
compiled_vars = compiled["vars"] = {}
|
|
|
|
for mood in config["mood"]:
|
|
compiled_moods[mood] = mood_definitions[mood]
|
|
del config["mood"]
|
|
compiled_vars.update(config)
|
|
|
|
return compiled
|