mirror of
https://github.com/Kozea/Radicale.git
synced 2025-09-15 20:36:55 +00:00
- Capture previous version of event pre-overwrite for use in notification hooks
- Use previous version of event in email hooks to determine added/deleted/updated email type
This commit is contained in:
parent
e4b337d3ff
commit
80dc4995cf
10 changed files with 274 additions and 110 deletions
|
@ -323,7 +323,7 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
|||
if "W" in self._rights.authorization(user, principal_path):
|
||||
with self._storage.acquire_lock("w", user):
|
||||
try:
|
||||
new_coll = self._storage.create_collection(principal_path)
|
||||
new_coll, _, _ = self._storage.create_collection(principal_path)
|
||||
if new_coll:
|
||||
jsn_coll = self.configuration.get("storage", "predefined_collections")
|
||||
for (name_coll, props) in jsn_coll.items():
|
||||
|
|
|
@ -24,7 +24,7 @@ from typing import Optional
|
|||
|
||||
from radicale import httputils, storage, types, xmlutils
|
||||
from radicale.app.base import Access, ApplicationBase
|
||||
from radicale.hook import DeleteHookNotificationItem
|
||||
from radicale.hook import HookNotificationItem, HookNotificationItemTypes
|
||||
from radicale.log import logger
|
||||
|
||||
|
||||
|
@ -82,10 +82,12 @@ class ApplicationPartDelete(ApplicationBase):
|
|||
return httputils.NOT_ALLOWED
|
||||
for i in item.get_all():
|
||||
hook_notification_item_list.append(
|
||||
DeleteHookNotificationItem(
|
||||
access.path,
|
||||
i.uid,
|
||||
old_content=item.serialize() # type: ignore
|
||||
HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.DELETE,
|
||||
path=access.path,
|
||||
uid=i.uid,
|
||||
old_content=item.serialize(), # type: ignore
|
||||
new_content=None
|
||||
)
|
||||
)
|
||||
xml_answer = xml_delete(base_prefix, path, item)
|
||||
|
@ -93,10 +95,12 @@ class ApplicationPartDelete(ApplicationBase):
|
|||
assert item.collection is not None
|
||||
assert item.href is not None
|
||||
hook_notification_item_list.append(
|
||||
DeleteHookNotificationItem(
|
||||
access.path,
|
||||
item.uid,
|
||||
old_content=item.serialize() # type: ignore
|
||||
HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.DELETE,
|
||||
path=access.path,
|
||||
uid=item.uid,
|
||||
old_content=item.serialize(), # type: ignore
|
||||
new_content=None,
|
||||
)
|
||||
)
|
||||
xml_answer = xml_delete(
|
||||
|
|
|
@ -102,9 +102,9 @@ class ApplicationPartProppatch(ApplicationBase):
|
|||
item)
|
||||
if xml_content is not None:
|
||||
hook_notification_item = HookNotificationItem(
|
||||
HookNotificationItemTypes.CPATCH,
|
||||
access.path,
|
||||
DefusedET.tostring(
|
||||
notification_item_type=HookNotificationItemTypes.CPATCH,
|
||||
path=access.path,
|
||||
new_content=DefusedET.tostring(
|
||||
xml_content,
|
||||
encoding=self._encoding
|
||||
).decode(encoding=self._encoding)
|
||||
|
|
|
@ -243,14 +243,27 @@ class ApplicationPartPut(ApplicationBase):
|
|||
|
||||
if write_whole_collection:
|
||||
try:
|
||||
etag = self._storage.create_collection(
|
||||
path, prepared_items, props).etag
|
||||
col, replaced_items, new_item_hrefs = self._storage.create_collection(
|
||||
href=path,
|
||||
items=prepared_items,
|
||||
props=props)
|
||||
for item in prepared_items:
|
||||
hook_notification_item = HookNotificationItem(
|
||||
HookNotificationItemTypes.UPSERT,
|
||||
access.path,
|
||||
item.serialize()
|
||||
)
|
||||
# Try to grab the previously-existing item by href
|
||||
existing_item = replaced_items.get(item.href, None)
|
||||
if existing_item:
|
||||
hook_notification_item = HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.UPSERT,
|
||||
path=access.path,
|
||||
old_content=existing_item.serialize(),
|
||||
new_content=item.serialize()
|
||||
)
|
||||
else: # We assume the item is new because it was not in the replaced_items
|
||||
hook_notification_item = HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.UPSERT,
|
||||
path=access.path,
|
||||
old_content=None,
|
||||
new_content=item.serialize()
|
||||
)
|
||||
self._hook.notify(hook_notification_item)
|
||||
except ValueError as e:
|
||||
logger.warning(
|
||||
|
@ -267,12 +280,23 @@ class ApplicationPartPut(ApplicationBase):
|
|||
|
||||
href = posixpath.basename(pathutils.strip_path(path))
|
||||
try:
|
||||
etag = parent_item.upload(href, prepared_item).etag
|
||||
hook_notification_item = HookNotificationItem(
|
||||
HookNotificationItemTypes.UPSERT,
|
||||
access.path,
|
||||
prepared_item.serialize()
|
||||
)
|
||||
uploaded_item, replaced_item = parent_item.upload(href, prepared_item)
|
||||
etag = uploaded_item.etag
|
||||
if replaced_item:
|
||||
# If the item was replaced, we notify with the old content
|
||||
hook_notification_item = HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.UPSERT,
|
||||
path=access.path,
|
||||
old_content=replaced_item.serialize(),
|
||||
new_content=prepared_item.serialize()
|
||||
)
|
||||
else: # If it was a new item, we notify with no old content
|
||||
hook_notification_item = HookNotificationItem(
|
||||
notification_item_type=HookNotificationItemTypes.UPSERT,
|
||||
path=access.path,
|
||||
old_content=None,
|
||||
new_content=prepared_item.serialize()
|
||||
)
|
||||
self._hook.notify(hook_notification_item)
|
||||
except ValueError as e:
|
||||
# return better matching HTTP result in case errno is provided and catched
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue