1
0
Fork 0
mirror of https://github.com/Kozea/Radicale.git synced 2025-08-04 18:22:26 +00:00
Radicale/radicale/hook/__init__.py

81 lines
2.3 KiB
Python
Raw Normal View History

2020-08-17 02:14:04 +02:00
import json
2020-08-17 02:23:49 +02:00
from enum import Enum
2024-03-02 19:44:10 +01:00
from typing import Sequence
2020-08-17 02:14:04 +02:00
from radicale import pathutils, utils
from radicale.log import logger
2020-08-17 02:05:02 +02:00
2025-06-19 02:00:09 -06:00
INTERNAL_TYPES: Sequence[str] = ("none", "rabbitmq", "email")
2020-08-17 02:05:02 +02:00
def load(configuration):
"""Load the storage module chosen in configuration."""
try:
return utils.load_plugin(
INTERNAL_TYPES, "hook", "Hook", BaseHook, configuration)
except Exception as e:
2024-08-27 21:34:52 +02:00
logger.warning(e)
logger.warning("Hook \"%s\" failed to load, falling back to \"none\"." % configuration.get("hook", "type"))
configuration = configuration.copy()
configuration.update({"hook": {"type": "none"}}, "hook", privileged=True)
return utils.load_plugin(
INTERNAL_TYPES, "hook", "Hook", BaseHook, configuration)
2020-08-17 02:05:02 +02:00
class BaseHook:
def __init__(self, configuration):
"""Initialize BaseHook.
``configuration`` see ``radicale.config`` module.
The ``configuration`` must not change during the lifetime of
this object, it is kept as an internal reference.
"""
self.configuration = configuration
2020-08-17 02:14:04 +02:00
def notify(self, notification_item):
2020-08-17 02:05:02 +02:00
"""Upload a new or replace an existing item."""
raise NotImplementedError
2020-08-17 02:14:04 +02:00
class HookNotificationItemTypes(Enum):
2020-08-19 01:38:49 +02:00
CPATCH = "cpatch"
2020-08-17 02:14:04 +02:00
UPSERT = "upsert"
DELETE = "delete"
def _cleanup(path):
sane_path = pathutils.strip_path(path)
attributes = sane_path.split("/") if sane_path else []
if len(attributes) < 2:
return ""
return attributes[0] + "/" + attributes[1]
2020-08-17 02:14:04 +02:00
class HookNotificationItem:
def __init__(self, notification_item_type, path, uid=None, new_content=None, old_content=None):
2020-08-17 02:14:04 +02:00
self.type = notification_item_type.value
self.point = _cleanup(path)
self.uid = uid
self.new_content = new_content
self.old_content = old_content
@property
def content(self): # For backward compatibility
return self.uid or self.new_content or self.old_content
@property
def replaces_existing_item(self) -> bool:
"""Check if this notification item replaces/deletes an existing item."""
return self.old_content is not None
2020-08-17 02:14:04 +02:00
def to_json(self):
2020-08-17 02:37:21 +02:00
return json.dumps(
self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4
)