Compare commits
No commits in common. "d6e24aa359e94ceab09bc980e403ff0fa7a2d047" and "1e374c61e6e7859a52212a1b6b93793a764b8b1c" have entirely different histories.
d6e24aa359
...
1e374c61e6
|
@ -1,5 +1,5 @@
|
||||||
FROM python:3.11-alpine
|
FROM python:3.11-alpine
|
||||||
RUN python3 -m pip --no-cache-dir install bleach jinja2 markdown matrix-nio
|
RUN python3 -m pip --no-cache-dir install bleach markdown matrix-nio
|
||||||
ADD matrixchat-notify.py /bin/
|
ADD matrixchat-notify.py /bin/
|
||||||
ADD matrixchat-notify-config.json /etc/
|
ADD matrixchat-notify-config.json /etc/
|
||||||
RUN chmod +x /bin/matrixchat-notify.py
|
RUN chmod +x /bin/matrixchat-notify.py
|
||||||
|
|
36
README.md
36
README.md
|
@ -40,7 +40,7 @@ steps:
|
||||||
* `allowed_tags` *(default:* [`DEFAULT_ALLOWED_TAGS`]*)*
|
* `allowed_tags` *(default:* [`DEFAULT_ALLOWED_TAGS`]*)*
|
||||||
|
|
||||||
List or set or string with comma-separated list of HTML tag names. HTML
|
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.
|
rendering a Markdown message template.
|
||||||
|
|
||||||
Note that the default list does not include any tags, which allow to load
|
Note that the default list does not include any tags, which allow to load
|
||||||
|
@ -64,28 +64,11 @@ steps:
|
||||||
|
|
||||||
The Matrix homeserver URL.
|
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`
|
* `markdown`
|
||||||
|
|
||||||
If set to `yes`, `y`, `true`, `t`, `on` or `1`, the message resulting from
|
If set to `yes`, `y`, `true` or `on`, the message resulting from template
|
||||||
template substtution is considered to be in Markdown format and will be
|
substtution is considered to be in Markdown format and will be rendered to
|
||||||
rendered to HTML and sent as a formatted message with the format set to
|
HTML and sent as a formatted message with `org.matrix.custom.html` format.
|
||||||
`org.matrix.custom.html`.
|
|
||||||
|
|
||||||
Using this feature requires the `markdown` and `bleach` Python modules to
|
|
||||||
be available (they are installed by default in the plugin's docker image).
|
|
||||||
|
|
||||||
* `markdown_extensions` *(default:* `admonition, extra, sane_lists, smarty`)
|
* `markdown_extensions` *(default:* `admonition, extra, sane_lists, smarty`)
|
||||||
|
|
||||||
|
@ -112,9 +95,9 @@ steps:
|
||||||
|
|
||||||
* `template` *(default:* `${DRONE_BUILD_STATUS}`*)*
|
* `template` *(default:* `${DRONE_BUILD_STATUS}`*)*
|
||||||
|
|
||||||
The message template. Valid placeholders (example: `${DRONE_REPO}`) will be
|
The message template. Valid placeholders of the form `${PLACEHOLDER}` will
|
||||||
substituted with the values of the matching environment variables (subject
|
be substituted with the values of the matching environment variables
|
||||||
to filtering according to the `pass_environment` setting).
|
(subject to filtering according to the `pass_environment` setting).
|
||||||
|
|
||||||
See this [reference] for environment variables available in drone.io CI
|
See this [reference] for environment variables available in drone.io CI
|
||||||
pipelines.
|
pipelines.
|
||||||
|
@ -124,11 +107,10 @@ steps:
|
||||||
ID of user on homeserver to send message as (ID, not username).
|
ID of user on homeserver to send message as (ID, not username).
|
||||||
|
|
||||||
|
|
||||||
[`DEFAULT_ALLOWED_ATTRS`]: ./matrixchat-notify.py#L27
|
[`DEFAULT_ALLOWED_ATTRS`]: ./matrixchat-notify.py#L29
|
||||||
[`DEFAULT_ALLOWED_TAGS`]: ./matrixchat-notify.py#L34
|
[`DEFAULT_ALLOWED_TAGS`]: ./matrixchat-notify.py#L35
|
||||||
[allowed attributes]: https://bleach.readthedocs.io/en/latest/clean.html#allowed-attributes-attributes
|
[allowed attributes]: https://bleach.readthedocs.io/en/latest/clean.html#allowed-attributes-attributes
|
||||||
[drone.io]: https://drone.io/
|
[drone.io]: https://drone.io/
|
||||||
[jinja]: https://jinja.palletsprojects.com/
|
|
||||||
[list of extensions]: https://python-markdown.github.io/extensions/
|
[list of extensions]: https://python-markdown.github.io/extensions/
|
||||||
[plugin]: https://docs.drone.io/plugins/overview/
|
[plugin]: https://docs.drone.io/plugins/overview/
|
||||||
[reference]: https://docs.drone.io/pipeline/environment/reference/
|
[reference]: https://docs.drone.io/pipeline/environment/reference/
|
||||||
|
|
|
@ -5,7 +5,6 @@ Requires:
|
||||||
|
|
||||||
* <https://pypi.org/project/matrix-nio>
|
* <https://pypi.org/project/matrix-nio>
|
||||||
* Optional: <https://pypi.org/project/bleach/>
|
* Optional: <https://pypi.org/project/bleach/>
|
||||||
* Optional: <https://pypi.org/project/Jinja2/>
|
|
||||||
* Optional: <https://pypi.org/project/markdown/>
|
* Optional: <https://pypi.org/project/markdown/>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -21,47 +20,36 @@ from distutils.util import strtobool
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
from string import Template
|
from string import Template
|
||||||
|
|
||||||
|
import bleach
|
||||||
from nio import AsyncClient, LoginResponse
|
from nio import AsyncClient, LoginResponse
|
||||||
|
|
||||||
PROG = "matrixchat-notify"
|
PROG = "matrixchat-notify"
|
||||||
CONFIG_FILENAME = f"{PROG}-config.json"
|
CONFIG_FILENAME = f"{PROG}-config.json"
|
||||||
DEFAULT_ALLOWED_ATTRS = {
|
DEFAULT_ALLOWED_ATTRS = bleach.ALLOWED_ATTRIBUTES.copy()
|
||||||
|
DEFAULT_ALLOWED_ATTRS.update(
|
||||||
|
{
|
||||||
"*": ["class"],
|
"*": ["class"],
|
||||||
"a": ["href", "title"],
|
|
||||||
"abbr": ["title"],
|
|
||||||
"acronym": ["title"],
|
|
||||||
"img": ["alt", "src"],
|
"img": ["alt", "src"],
|
||||||
}
|
}
|
||||||
DEFAULT_ALLOWED_TAGS = {
|
)
|
||||||
"a",
|
DEFAULT_ALLOWED_TAGS = bleach.ALLOWED_TAGS | {
|
||||||
"abbr",
|
|
||||||
"acronym",
|
|
||||||
"b",
|
|
||||||
"blockquote",
|
|
||||||
"code",
|
|
||||||
"dd",
|
"dd",
|
||||||
"div",
|
"div",
|
||||||
"dl",
|
"dl",
|
||||||
"dt",
|
"dt",
|
||||||
"em",
|
|
||||||
"h1",
|
"h1",
|
||||||
"h2",
|
"h2",
|
||||||
"h3",
|
"h3",
|
||||||
"h4",
|
"h4",
|
||||||
"h5",
|
"h5",
|
||||||
"h6",
|
"h6",
|
||||||
"i",
|
|
||||||
"li",
|
|
||||||
"ol",
|
|
||||||
"p",
|
"p",
|
||||||
"span",
|
"span",
|
||||||
"strong",
|
|
||||||
"table",
|
"table",
|
||||||
"td",
|
"td",
|
||||||
"th",
|
"th",
|
||||||
"thead",
|
"thead",
|
||||||
"tr",
|
"tr",
|
||||||
"ul",
|
|
||||||
}
|
}
|
||||||
DEFAULT_HOMESERVER = "https://matrix.org"
|
DEFAULT_HOMESERVER = "https://matrix.org"
|
||||||
DEFAULT_MARKDOWN_EXTENSIONS = "admonition, extra, sane_lists, smarty"
|
DEFAULT_MARKDOWN_EXTENSIONS = "admonition, extra, sane_lists, smarty"
|
||||||
|
@ -74,7 +62,6 @@ SETTINGS_KEYS = (
|
||||||
"deviceid",
|
"deviceid",
|
||||||
"devicename",
|
"devicename",
|
||||||
"homeserver",
|
"homeserver",
|
||||||
"jinja",
|
|
||||||
"markdown",
|
"markdown",
|
||||||
"markdown_extensions",
|
"markdown_extensions",
|
||||||
"pass_environment",
|
"pass_environment",
|
||||||
|
@ -88,7 +75,7 @@ log = logging.getLogger(PROG)
|
||||||
|
|
||||||
def tobool(s):
|
def tobool(s):
|
||||||
try:
|
try:
|
||||||
return strtobool(str(s))
|
return strtobool(s)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -158,15 +145,15 @@ async def send_notification(config, message):
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
|
|
||||||
def get_template_context(config):
|
def render_message(config):
|
||||||
pass_environment = config.get("pass_environment", [])
|
pass_environment = config.get("pass_environment", "")
|
||||||
|
|
||||||
if not isinstance(pass_environment, list):
|
if not isinstance(pass_environment, list):
|
||||||
pass_environment = [pass_environment]
|
pass_environment = [pass_environment]
|
||||||
|
|
||||||
patterns = []
|
patterns = []
|
||||||
for value in pass_environment:
|
for value in pass_environment:
|
||||||
# expand any comma-separated names/patterns
|
# expand any comma-separetd names/patterns
|
||||||
if "," in value:
|
if "," in value:
|
||||||
patterns.extend([p.strip() for p in value.split(",") if p.strip()])
|
patterns.extend([p.strip() for p in value.split(",") if p.strip()])
|
||||||
else:
|
else:
|
||||||
|
@ -178,28 +165,12 @@ def get_template_context(config):
|
||||||
for pattern in patterns:
|
for pattern in patterns:
|
||||||
filtered_names.update(fnmatch.filter(env_names, pattern))
|
filtered_names.update(fnmatch.filter(env_names, pattern))
|
||||||
|
|
||||||
return {name: os.environ[name] for name in tuple(filtered_names)}
|
context = {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)
|
template = config.get("template", DEFAULT_TEMPLATE)
|
||||||
|
|
||||||
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)
|
return Template(template).safe_substitute(context)
|
||||||
|
|
||||||
|
|
||||||
def render_markdown(message, config):
|
def render_markdown(message, config):
|
||||||
import bleach
|
|
||||||
import markdown
|
import markdown
|
||||||
|
|
||||||
allowed_attrs = config.get("allowed_attrs", DEFAULT_ALLOWED_ATTRS)
|
allowed_attrs = config.get("allowed_attrs", DEFAULT_ALLOWED_ATTRS)
|
||||||
|
|
Loading…
Reference in New Issue