- Check if hook is enabled before constructing hook notification items

- Skip/early exit email hook if notification item is not a VCALENDAR
This commit is contained in:
Nate Harris
2026-03-30 01:55:03 -06:00
parent 89edf01757
commit 3b9df7b87e
7 changed files with 123 additions and 61 deletions

View File

@@ -33,6 +33,11 @@ class BaseHook:
"""
self.configuration = configuration
@property
def enabled(self) -> bool:
"""Check if this hook is enabled."""
raise NotImplementedError
def notify(self, notification_item):
"""Upload a new or replace an existing item."""
raise NotImplementedError
@@ -55,10 +60,12 @@ def _cleanup(path):
class HookNotificationItem:
def __init__(self, notification_item_type, path, content=None, uid=None, new_content=None, old_content=None):
def __init__(self, notification_item_type, path, content=None, content_type=None, uid=None, new_content=None,
old_content=None):
self.type = notification_item_type.value
self.point = _cleanup(path)
self._content_legacy = content
self.content_type = content_type
self.uid = uid
self.new_content = new_content
self.old_content = old_content
@@ -67,6 +74,30 @@ class HookNotificationItem:
def content(self): # For backward compatibility
return self._content_legacy or self.uid or self.new_content or self.old_content
@property
def is_calendar_item(self) -> bool:
"""Check if this notification item is related to a VCALENDAR item."""
if not self.content_type:
return False
return self.content_type.upper().strip() == "VCALENDAR"
@property
def is_card_item(self) -> bool:
"""Check if this notification item is related to a VCARD item."""
if not self.content_type:
return False
return self.content_type.upper().strip() == "VCARD"
@property
def is_addressbook_item(self) -> bool:
"""Check if this notification item is related to a VADDRESSBOOK item."""
if not self.content_type:
return False
return self.content_type.upper().strip() == "VADDRESSBOOK"
@property
def replaces_existing_item(self) -> bool:
"""Check if this notification item replaces/deletes an existing item."""

View File

@@ -930,12 +930,21 @@ class Hook(BaseHook):
self.email_config
)
@property
def enabled(self) -> bool:
"""Check if this hook is enabled (has a notify method)."""
return self.email_config.host is not None
def notify(self, notification_item) -> None:
"""
Entrypoint for processing a single notification item.
Overrides default notify method from BaseHook.
Triggered by Radicale when a notifiable event occurs (e.g. item added, updated or deleted)
"""
# Skip any non-VCALENDAR items
if not notification_item.is_calendar_item:
return
if isinstance(notification_item, HookNotificationItem):
self._process_event_and_notify(notification_item)

View File

@@ -2,5 +2,10 @@ from radicale import hook
class Hook(hook.BaseHook):
@property
def enabled(self) -> bool:
"""Check if this hook is enabled."""
return False
def notify(self, notification_item):
"""Notify nothing. Empty hook."""

View File

@@ -53,6 +53,11 @@ class Hook(hook.BaseHook):
logger.debug("Hook 'rabbitmq': _make_declare_queue_synced")
self._channel.queue_declare(queue=self._topic, durable=True, arguments={"x-queue-type": self._queue_type})
@property
def enabled(self) -> bool:
"""Check if this hook is enabled."""
return self._endpoint is not None
def notify(self, notification_item):
if isinstance(notification_item, HookNotificationItem):
self._notify(notification_item, True)