105 lines
3.0 KiB
Python
105 lines
3.0 KiB
Python
import json
|
|
import os
|
|
import re
|
|
import tomllib
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import dotenv
|
|
from jinja2 import Environment
|
|
|
|
from ..preset.model import Variables
|
|
|
|
|
|
def do_bool(data: str | None) -> bool:
|
|
if data is None:
|
|
return False
|
|
if not isinstance(data, str):
|
|
data = str(data)
|
|
return data.lower() not in ["false", "null", "none", "0", ""]
|
|
|
|
|
|
def do_env(key: str, default: str | None = None) -> str | None:
|
|
return os.environ.get(key=key.upper(), default=default)
|
|
|
|
|
|
def do_not(value: Any | None) -> bool:
|
|
return not do_bool(str(value))
|
|
|
|
|
|
def _build_env(basepath: Path) -> Environment:
|
|
env = Environment()
|
|
|
|
def do_file(filename: str) -> Path | None:
|
|
result = Path(filename)
|
|
if not result.is_absolute():
|
|
result = basepath / result
|
|
if result.exists():
|
|
return result
|
|
return None
|
|
|
|
def do_read(filename: str) -> dict | None:
|
|
path = do_file(filename)
|
|
if path:
|
|
if path.suffix == ".toml":
|
|
return tomllib.loads(path.read_text())
|
|
if path.suffix == ".json":
|
|
return json.loads(path.read_text())
|
|
if path.suffix == ".env" or path.name == ".env":
|
|
return dotenv.dotenv_values(path)
|
|
return None
|
|
|
|
def do_get(data: dict | None, keypath: str) -> str | None:
|
|
if not data:
|
|
return None
|
|
path = keypath.split(".")
|
|
result = data.get(path[0])
|
|
for key in path[1:]:
|
|
if result:
|
|
result = result.get(key)
|
|
return result
|
|
|
|
def do_search(data: str | None, pattern: str, position: int = 1) -> str | None:
|
|
if not data:
|
|
return None
|
|
matched = re.compile(pattern).search(data)
|
|
if matched:
|
|
return matched.group(position)
|
|
return None
|
|
|
|
def do_key(data: dict | None, keyindex: int = 0) -> str | None:
|
|
if not data:
|
|
return None
|
|
keys = list(data.keys())
|
|
return keys[keyindex]
|
|
|
|
env.filters["file"] = do_file
|
|
env.filters["read"] = do_read
|
|
env.filters["get"] = do_get
|
|
env.filters["search"] = do_search
|
|
env.filters["key"] = do_key
|
|
env.filters["bool"] = do_bool
|
|
env.filters["env"] = do_env
|
|
env.filters["not"] = do_not
|
|
return env
|
|
|
|
|
|
class PathTemplate:
|
|
def __init__(self, basepath: Path):
|
|
self._basepath = basepath
|
|
self._env = _build_env(basepath)
|
|
|
|
def update_variables(self, templates: Variables, variables: Variables):
|
|
for k, v in templates.items():
|
|
variables[k] = self._env.from_string(v).render(**variables)
|
|
|
|
def fill_template(self, template: str, variables: Variables) -> str:
|
|
return self._env.from_string(template).render(**variables)
|
|
|
|
def check_conditions(self, templates: list[str], variables: Variables) -> bool:
|
|
for template in templates:
|
|
value = self.fill_template(template, variables)
|
|
if not do_bool(value):
|
|
return False
|
|
return True
|