template: add support for Jinja2 template evaluation
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
3f7cc53baa
commit
2142d344dd
|
@ -0,0 +1,66 @@
|
|||
# Template Factory helper
|
||||
#
|
||||
# Copyright (C) 2021 Eric Callahan <arksine.code@gmail.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
from __future__ import annotations
|
||||
import logging
|
||||
import jinja2
|
||||
import json
|
||||
|
||||
# Annotation imports
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from moonraker import Server
|
||||
from confighelper import ConfigHelper
|
||||
|
||||
class TemplateFactory:
|
||||
def __init__(self, config: ConfigHelper) -> None:
|
||||
self.server = config.get_server()
|
||||
self.jenv = jinja2.Environment('{%', '%}', '{', '}')
|
||||
self.jenv.add_extension("jinja2.ext.do")
|
||||
self.jenv.filters['fromjson'] = json.loads
|
||||
self.add_environment_global('raise_error', self._raise_error)
|
||||
|
||||
def add_environment_global(self, name: str, value: Any):
|
||||
if name in self.jenv.globals:
|
||||
raise self.server.error(
|
||||
f"Jinja 2 environment already contains global {name}")
|
||||
self.jenv.globals[name] = value
|
||||
|
||||
def _raise_error(self, err_msg: str, err_code: int = 400) -> None:
|
||||
raise self.server.error(err_msg, err_code)
|
||||
|
||||
def create_template(self, source: str) -> JinjaTemplate:
|
||||
return JinjaTemplate(source, self.server, self.jenv)
|
||||
|
||||
class JinjaTemplate:
|
||||
def __init__(self,
|
||||
source: str,
|
||||
server: Server,
|
||||
env: jinja2.Environment
|
||||
) -> None:
|
||||
self.server = server
|
||||
self.orig_source = source.strip()
|
||||
try:
|
||||
self.template = env.from_string(self.orig_source)
|
||||
except Exception:
|
||||
logging.exception(f"Error creating template from source:\n{source}")
|
||||
raise
|
||||
|
||||
def render(self, context: Dict[str, Any] = {}) -> str:
|
||||
try:
|
||||
return self.template.render(context).strip()
|
||||
except Exception as e:
|
||||
raise self.server.error("Error rendering template") from e
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.orig_source
|
||||
|
||||
def load_component(config: ConfigHelper) -> TemplateFactory:
|
||||
return TemplateFactory(config)
|
|
@ -11,3 +11,4 @@ paho-mqtt==1.5.1
|
|||
pycurl==7.44.1
|
||||
zeroconf==0.37.0
|
||||
preprocess-cancellation==0.1.6
|
||||
jinja2==3.0.3
|
||||
|
|
Loading…
Reference in New Issue