notfiier: extend attach option
The "attach" option now accepts templates, such templates are passed the same context received by the body and title options. Additionally it is possible to specify multiple attachments by separating each attachment with a newline. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
40013ec270
commit
f29c896c4a
|
@ -8,6 +8,8 @@ from __future__ import annotations
|
||||||
|
|
||||||
import apprise
|
import apprise
|
||||||
import logging
|
import logging
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
|
||||||
# Annotation imports
|
# Annotation imports
|
||||||
from typing import (
|
from typing import (
|
||||||
|
@ -20,6 +22,7 @@ from typing import (
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..confighelper import ConfigHelper
|
from ..confighelper import ConfigHelper
|
||||||
from ..common import WebRequest
|
from ..common import WebRequest
|
||||||
|
from .file_manager.file_manager import FileManager
|
||||||
from .http_client import HttpClient
|
from .http_client import HttpClient
|
||||||
from .klippy_apis import KlippyAPI as APIComp
|
from .klippy_apis import KlippyAPI as APIComp
|
||||||
|
|
||||||
|
@ -163,7 +166,6 @@ class NotifierEvent:
|
||||||
|
|
||||||
class NotifierInstance:
|
class NotifierInstance:
|
||||||
def __init__(self, config: ConfigHelper) -> None:
|
def __init__(self, config: ConfigHelper) -> None:
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
name_parts = config.get_name().split(maxsplit=1)
|
name_parts = config.get_name().split(maxsplit=1)
|
||||||
if len(name_parts) != 2:
|
if len(name_parts) != 2:
|
||||||
|
@ -171,26 +173,16 @@ class NotifierInstance:
|
||||||
self.server = config.get_server()
|
self.server = config.get_server()
|
||||||
self.name = name_parts[1]
|
self.name = name_parts[1]
|
||||||
self.apprise = apprise.Apprise()
|
self.apprise = apprise.Apprise()
|
||||||
self.warned = False
|
self.attach = config.gettemplate("attach", None)
|
||||||
|
url_template = config.gettemplate("url")
|
||||||
self.attach_requires_file_system_check = True
|
|
||||||
self.attach = config.get("attach", None)
|
|
||||||
if self.attach is None or \
|
|
||||||
(self.attach.startswith("http://") or
|
|
||||||
self.attach.startswith("https://")):
|
|
||||||
self.attach_requires_file_system_check = False
|
|
||||||
|
|
||||||
url_template = config.gettemplate('url')
|
|
||||||
self.url = url_template.render()
|
self.url = url_template.render()
|
||||||
|
|
||||||
if len(self.url) < 2:
|
if re.match(r"\w+?://", self.url) is None:
|
||||||
raise config.error(f"Invalid url for: {config.get_name()}")
|
raise config.error(f"Invalid url for: {config.get_name()}")
|
||||||
|
|
||||||
self.title = config.gettemplate('title', None)
|
self.title = config.gettemplate("title", None)
|
||||||
self.body = config.gettemplate("body", None)
|
self.body = config.gettemplate("body", None)
|
||||||
|
|
||||||
self.events: List[str] = config.getlist("events", separator=",")
|
self.events: List[str] = config.getlist("events", separator=",")
|
||||||
|
|
||||||
self.apprise.add(self.url)
|
self.apprise.add(self.url)
|
||||||
|
|
||||||
def as_dict(self):
|
def as_dict(self):
|
||||||
|
@ -206,7 +198,6 @@ class NotifierInstance:
|
||||||
async def notify(
|
async def notify(
|
||||||
self, event_name: str, event_args: List, message: str = ""
|
self, event_name: str, event_args: List, message: str = ""
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"event_name": event_name,
|
"event_name": event_name,
|
||||||
"event_args": event_args,
|
"event_args": event_args,
|
||||||
|
@ -221,22 +212,46 @@ class NotifierInstance:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verify the attachment
|
# Verify the attachment
|
||||||
if self.attach_requires_file_system_check and self.attach is not None:
|
attachments: List[str] = []
|
||||||
fm = self.server.lookup_component("file_manager")
|
if self.attach is not None:
|
||||||
if not fm.can_access_path(self.attach):
|
fm: FileManager = self.server.lookup_component("file_manager")
|
||||||
if not self.warned:
|
try:
|
||||||
self.server.add_warning(
|
rendered = self.attach.render(context)
|
||||||
f"Attachment of notifier '{self.name}' is not "
|
except self.server.error:
|
||||||
"valid. The location of the "
|
logging.exception(f"notifier {self.name}: Failed to render attachment")
|
||||||
"attachment is not "
|
self.server.add_warning(
|
||||||
"accessible.")
|
f"[notifier {self.name}]: The attachment is not valid. The "
|
||||||
self.warned = True
|
"template failed to render.",
|
||||||
|
f"notifier {self.name}"
|
||||||
|
)
|
||||||
self.attach = None
|
self.attach = None
|
||||||
|
else:
|
||||||
|
for item in rendered.splitlines():
|
||||||
|
item = item.strip()
|
||||||
|
if not item:
|
||||||
|
continue
|
||||||
|
if re.match(r"https?://", item) is not None:
|
||||||
|
# Attachment is a url, system check not necessary
|
||||||
|
attachments.append(item)
|
||||||
|
continue
|
||||||
|
attach_path = pathlib.Path(item).expanduser().resolve()
|
||||||
|
if not attach_path.is_file():
|
||||||
|
self.server.add_warning(
|
||||||
|
f"[notifier {self.name}]: Invalid attachment detected, "
|
||||||
|
f"file does not exist: {attach_path}.",
|
||||||
|
f"notifier {self.name}"
|
||||||
|
)
|
||||||
|
elif not fm.can_access_path(attach_path):
|
||||||
|
self.server.add_warning(
|
||||||
|
f"[notifier {self.name}]: Invalid attachment detected, "
|
||||||
|
f"no read permission for the file {attach_path}.",
|
||||||
|
f"notifier {self.name}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
attachments.append(str(attach_path))
|
||||||
await self.apprise.async_notify(
|
await self.apprise.async_notify(
|
||||||
rendered_body.strip(),
|
rendered_body.strip(), rendered_title.strip(),
|
||||||
rendered_title.strip(),
|
attach=None if not attachments else attachments
|
||||||
attach=self.attach
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
|
|
Loading…
Reference in New Issue