feat: support rendering message template with Jinja
Add config setting to enable Jinja templates Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
		
							parent
							
								
									92d85d31bf
								
							
						
					
					
						commit
						d6e24aa359
					
				@ -1,5 +1,5 @@
 | 
			
		||||
FROM python:3.11-alpine
 | 
			
		||||
RUN python3 -m pip --no-cache-dir install bleach markdown matrix-nio
 | 
			
		||||
RUN python3 -m pip --no-cache-dir install bleach jinja2 markdown matrix-nio
 | 
			
		||||
ADD matrixchat-notify.py /bin/
 | 
			
		||||
ADD matrixchat-notify-config.json /etc/
 | 
			
		||||
RUN chmod +x /bin/matrixchat-notify.py
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										33
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								README.md
									
									
									
									
									
								
							@ -40,7 +40,7 @@ steps:
 | 
			
		||||
* `allowed_tags` *(default:* [`DEFAULT_ALLOWED_TAGS`]*)*
 | 
			
		||||
 | 
			
		||||
    List or set or string with comma-separated list of HTML tag names. HTML
 | 
			
		||||
    tags not included, will be stripped from the HTML output generated by
 | 
			
		||||
    tags not included will be stripped from the HTML output generated by
 | 
			
		||||
    rendering a Markdown message template.
 | 
			
		||||
 | 
			
		||||
    Note that the default list does not include any tags, which allow to load
 | 
			
		||||
@ -64,14 +64,28 @@ steps:
 | 
			
		||||
 | 
			
		||||
    The Matrix homeserver URL.
 | 
			
		||||
 | 
			
		||||
* `jinja`
 | 
			
		||||
 | 
			
		||||
    If set to `yes`, `y`, `true`, `t`, `on` or `1`, the message template is
 | 
			
		||||
    rendered with the [Jinja] templating engine (instead of performing simple
 | 
			
		||||
    placeholder substitution). The template context is controlled by the
 | 
			
		||||
    `pass_environment` setting, same as with non-Jinja templates, but
 | 
			
		||||
    placeholders use a different syntax (example: `{{DRONE_REPO}}`), so the
 | 
			
		||||
    `template` setting should be changed to be a valid Jinja2 template string
 | 
			
		||||
    when this is enabled.
 | 
			
		||||
 | 
			
		||||
    Using this feature requires the `jinja2` Python module to be available
 | 
			
		||||
    (it is installed by default in the plugin's docker image).
 | 
			
		||||
 | 
			
		||||
* `markdown`
 | 
			
		||||
 | 
			
		||||
    If set to `yes`, `y`, `true` or `on`, the message resulting from template
 | 
			
		||||
    substtution is considered to be in Markdown format and will be rendered to
 | 
			
		||||
    HTML and sent as a formatted message with `org.matrix.custom.html` format.
 | 
			
		||||
    If set to `yes`, `y`, `true`, `t`, `on` or `1`, the message resulting from
 | 
			
		||||
    template substtution is considered to be in Markdown format and will be
 | 
			
		||||
    rendered to HTML and sent as a formatted message with the format set to
 | 
			
		||||
    `org.matrix.custom.html`.
 | 
			
		||||
 | 
			
		||||
    Using this feature requires the `markdown` and `bleach` Python modules to
 | 
			
		||||
    be available (the plugin's docker image has them installed).
 | 
			
		||||
    be available (they are installed by default in the plugin's docker image).
 | 
			
		||||
 | 
			
		||||
* `markdown_extensions` *(default:* `admonition, extra, sane_lists, smarty`)
 | 
			
		||||
 | 
			
		||||
@ -98,9 +112,9 @@ steps:
 | 
			
		||||
 | 
			
		||||
* `template` *(default:* `${DRONE_BUILD_STATUS}`*)*
 | 
			
		||||
 | 
			
		||||
    The message template. Valid placeholders of the form `${PLACEHOLDER}` will
 | 
			
		||||
    be substituted with the values of the matching environment variables
 | 
			
		||||
    (subject to filtering according to the `pass_environment` setting).
 | 
			
		||||
    The message template. Valid placeholders (example: `${DRONE_REPO}`) will be
 | 
			
		||||
    substituted with the values of the matching environment variables (subject
 | 
			
		||||
    to filtering according to the `pass_environment` setting).
 | 
			
		||||
 | 
			
		||||
    See this [reference] for environment variables available in drone.io CI
 | 
			
		||||
    pipelines.
 | 
			
		||||
@ -114,6 +128,7 @@ steps:
 | 
			
		||||
[`DEFAULT_ALLOWED_TAGS`]: ./matrixchat-notify.py#L34
 | 
			
		||||
[allowed attributes]: https://bleach.readthedocs.io/en/latest/clean.html#allowed-attributes-attributes
 | 
			
		||||
[drone.io]: https://drone.io/
 | 
			
		||||
[jinja]: https://jinja.palletsprojects.com/
 | 
			
		||||
[list of extensions]: https://python-markdown.github.io/extensions/
 | 
			
		||||
[plugin]: https://docs.drone.io/plugins/overview/
 | 
			
		||||
[reference]:  https://docs.drone.io/pipeline/environment/reference/
 | 
			
		||||
[reference]: https://docs.drone.io/pipeline/environment/reference/
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ Requires:
 | 
			
		||||
 | 
			
		||||
* <https://pypi.org/project/matrix-nio>
 | 
			
		||||
* Optional: <https://pypi.org/project/bleach/>
 | 
			
		||||
* Optional: <https://pypi.org/project/Jinja2/>
 | 
			
		||||
* Optional: <https://pypi.org/project/markdown/>
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
@ -73,6 +74,7 @@ SETTINGS_KEYS = (
 | 
			
		||||
    "deviceid",
 | 
			
		||||
    "devicename",
 | 
			
		||||
    "homeserver",
 | 
			
		||||
    "jinja",
 | 
			
		||||
    "markdown",
 | 
			
		||||
    "markdown_extensions",
 | 
			
		||||
    "pass_environment",
 | 
			
		||||
@ -86,7 +88,7 @@ log = logging.getLogger(PROG)
 | 
			
		||||
 | 
			
		||||
def tobool(s):
 | 
			
		||||
    try:
 | 
			
		||||
        return strtobool(s)
 | 
			
		||||
        return strtobool(str(s))
 | 
			
		||||
    except ValueError:
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
@ -156,15 +158,15 @@ async def send_notification(config, message):
 | 
			
		||||
    await client.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def render_message(config):
 | 
			
		||||
    pass_environment = config.get("pass_environment", "")
 | 
			
		||||
def get_template_context(config):
 | 
			
		||||
    pass_environment = config.get("pass_environment", [])
 | 
			
		||||
 | 
			
		||||
    if not isinstance(pass_environment, list):
 | 
			
		||||
        pass_environment = [pass_environment]
 | 
			
		||||
 | 
			
		||||
    patterns = []
 | 
			
		||||
    for value in pass_environment:
 | 
			
		||||
        # expand any comma-separetd names/patterns
 | 
			
		||||
        # expand any comma-separated names/patterns
 | 
			
		||||
        if "," in value:
 | 
			
		||||
            patterns.extend([p.strip() for p in value.split(",") if p.strip()])
 | 
			
		||||
        else:
 | 
			
		||||
@ -176,9 +178,24 @@ def render_message(config):
 | 
			
		||||
    for pattern in patterns:
 | 
			
		||||
        filtered_names.update(fnmatch.filter(env_names, pattern))
 | 
			
		||||
 | 
			
		||||
    context = {name: os.environ[name] for name in tuple(filtered_names)}
 | 
			
		||||
    return {name: os.environ[name] for name in tuple(filtered_names)}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def render_message(config):
 | 
			
		||||
    context = get_template_context(config)
 | 
			
		||||
    template = config.get("template", DEFAULT_TEMPLATE)
 | 
			
		||||
    return Template(template).safe_substitute(context)
 | 
			
		||||
 | 
			
		||||
    if tobool(config.get("jinja")):
 | 
			
		||||
        try:
 | 
			
		||||
            from jinja2.sandbox import SandboxedEnvironment
 | 
			
		||||
 | 
			
		||||
            env = SandboxedEnvironment()
 | 
			
		||||
            return env.from_string(template).render(context)
 | 
			
		||||
        except Exception as exc:
 | 
			
		||||
            log.error("Could not render Jinja2 template: %s", exc)
 | 
			
		||||
            return template
 | 
			
		||||
    else:
 | 
			
		||||
        return Template(template).safe_substitute(context)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def render_markdown(message, config):
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user