diff --git a/radicale/app/delete.py b/radicale/app/delete.py index c3a9b12a..c27b3917 100644 --- a/radicale/app/delete.py +++ b/radicale/app/delete.py @@ -21,7 +21,7 @@ from http import client from xml.etree import ElementTree as ET from radicale import app, httputils, storage, xmlutils -from radicale.hook.rabbitmq import QueueItem, QueueItemTypes +from radicale.hook import HookNotificationItem, HookNotificationItemTypes def xml_delete(base_prefix, path, collection, href=None): @@ -66,10 +66,14 @@ class ApplicationDeleteMixin: if isinstance(item, storage.BaseCollection): xml_answer = xml_delete(base_prefix, path, item) for item in item.get_all(): - self._hook.notify(QueueItem(QueueItemTypes.DELETE, item.uid)) + hook_notification_item = \ + HookNotificationItem(HookNotificationItemTypes.DELETE, item.uid) + self._hook.notify(hook_notification_item) else: xml_answer = xml_delete( base_prefix, path, item.collection, item.href) - self._hook.notify(QueueItem(QueueItemTypes.DELETE, item.uid)) + hook_notification_item = \ + HookNotificationItem(HookNotificationItemTypes.DELETE, item.uid) + self._hook.notify(hook_notification_item) headers = {"Content-Type": "text/xml; charset=%s" % self._encoding} return client.OK, headers, self._write_xml_content(xml_answer) diff --git a/radicale/app/put.py b/radicale/app/put.py index 8f675255..e97c0885 100644 --- a/radicale/app/put.py +++ b/radicale/app/put.py @@ -29,7 +29,7 @@ from radicale import app, httputils from radicale import item as radicale_item from radicale import pathutils, rights, storage, xmlutils from radicale.log import logger -from radicale.hook.rabbitmq import QueueItem, QueueItemTypes +from radicale.hook import HookNotificationItem, HookNotificationItemTypes MIMETYPE_TAGS = {value: key for key, value in xmlutils.MIMETYPES.items()} @@ -195,7 +195,9 @@ class ApplicationPutMixin: etag = self._storage.create_collection( path, prepared_items, props).etag for item in prepared_items: - self._hook.notify(QueueItem(QueueItemTypes.UPSERT, item.serialize())) + hook_notification_item = \ + HookNotificationItem(HookNotificationItemTypes.UPSERT, item.serialize()) + self._hook.notify(hook_notification_item) except ValueError as e: logger.warning( "Bad PUT request on %r: %s", path, e, exc_info=True) @@ -211,7 +213,9 @@ class ApplicationPutMixin: href = posixpath.basename(pathutils.strip_path(path)) try: etag = parent_item.upload(href, prepared_item).etag - self._hook.notify(QueueItem(QueueItemTypes.UPSERT, prepared_item.serialize())) + hook_notification_item = \ + HookNotificationItem(HookNotificationItemTypes.UPSERT, prepared_item.serialize()) + self._hook.notify(hook_notification_item) except ValueError as e: logger.warning( "Bad PUT request on %r: %s", path, e, exc_info=True) diff --git a/radicale/hook/__init__.py b/radicale/hook/__init__.py index 1dd1d1b8..46956faa 100644 --- a/radicale/hook/__init__.py +++ b/radicale/hook/__init__.py @@ -1,4 +1,7 @@ +import json + from radicale import utils +from enum import Enum INTERNAL_TYPES = ("none", "rabbitmq") @@ -20,6 +23,21 @@ class BaseHook: """ self.configuration = configuration - def notify(self, content): + def notify(self, notification_item): """Upload a new or replace an existing item.""" raise NotImplementedError + + +class HookNotificationItemTypes(Enum): + UPSERT = "upsert" + DELETE = "delete" + + +class HookNotificationItem: + + def __init__(self, notification_item_type, content): + self.type = notification_item_type.value + self.content = content + + def to_json(self): + return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) diff --git a/radicale/hook/none.py b/radicale/hook/none.py index 2e5eb049..b770ab67 100644 --- a/radicale/hook/none.py +++ b/radicale/hook/none.py @@ -2,5 +2,5 @@ from radicale import hook class Hook(hook.BaseHook): - def notify(self, content): + def notify(self, notification_item): """Notify nothing. Empty hook.""" diff --git a/radicale/hook/rabbitmq/__init__.py b/radicale/hook/rabbitmq/__init__.py index 43568125..9d24a65b 100644 --- a/radicale/hook/rabbitmq/__init__.py +++ b/radicale/hook/rabbitmq/__init__.py @@ -1,8 +1,7 @@ import pika -import json +from radicale.hook import HookNotificationItem from radicale import hook -from enum import Enum class Hook(hook.BaseHook): @@ -24,24 +23,9 @@ class Hook(hook.BaseHook): def _make_declare_queue_synced(self, topic): self.channel.queue_declare(queue=topic) - def notify(self, content): - if not isinstance(content, QueueItem): - return - self.channel.basic_publish(exchange='', - routing_key=self.topic, - body=content.to_json().encode(encoding=self.encoding)) - - -class QueueItemTypes(Enum): - UPSERT = "upsert" - DELETE = "delete" - - -class QueueItem: - - def __init__(self, queue_item_type, content): - self.type = queue_item_type.value - self.content = content - - def to_json(self): - return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4) + def notify(self, notification_item): + if isinstance(notification_item, HookNotificationItem): + self.channel.basic_publish( + exchange='', + routing_key=self.topic, + body=notification_item.to_json().encode(encoding=self.encoding))