feat(nc-webhook): handle folder rename via NodeRenamedEvent
NC fires one NodeRenamedEvent on a directory rename — children don't
get their own events. The handler bailed on both paths having no
supported extension. Now:
- New `handle_directory_rename(old, new)` in scan.py does a single
transaction of prefix-rewrites against photos.filepath, folders.path,
and source_roots.path. Cross-source-root case (Photos/x → Memories/x)
is treated as discard-the-old-subtree; scan_folder dispatched by the
subsequent NodeWritten/NodeCreated picks up the new root.
- Webhook renamed branch checks "both source and target are
directories" and calls the helper. File renames keep the existing
delete-old + scan-new-parent path.
Idempotent: the SQL matches zero rows the second time around. That
makes the feedback loop safe — mule's existing PATCH /folders/{id}
endpoint already does a WebDAV MOVE + inline DB rewrite for NC paths,
and the resulting NodeRenamedEvent now flows back through this handler
without re-running the rewrite or leaving rows stale.
Trashbin restore (the documented "NC doesn't emit a subscribed event"
gap) is unchanged.
This commit is contained in:
@@ -130,6 +130,7 @@ async def nc_webhook(
|
||||
scan_folder,
|
||||
handle_file_deletion,
|
||||
handle_directory_deletion,
|
||||
handle_directory_rename,
|
||||
)
|
||||
|
||||
supported = _supported_extensions()
|
||||
@@ -183,9 +184,35 @@ async def nc_webhook(
|
||||
target = event.get("target") or {}
|
||||
old_abs = _nc_path_to_abs(source.get("path") or "")
|
||||
new_abs = _nc_path_to_abs(target.get("path") or "")
|
||||
if old_abs and Path(old_abs).suffix.lower() in supported:
|
||||
if not old_abs or not new_abs:
|
||||
return {"status": "ignored", "reason": "non-user-files path"}
|
||||
|
||||
old_is_dir = Path(old_abs).suffix.lower() not in supported
|
||||
new_is_dir = Path(new_abs).suffix.lower() not in supported
|
||||
|
||||
# Directory rename: NC fires one event for the directory; the
|
||||
# children's paths change implicitly. Prefix-rewrite in mule.
|
||||
# Same handler covers the feedback case where the PATCH
|
||||
# /folders/{id}/rename endpoint already updated the DB — the
|
||||
# SQL UPDATE matches zero rows the second time around.
|
||||
if old_is_dir and new_is_dir:
|
||||
result = await handle_directory_rename(old_abs, new_abs)
|
||||
logger.info(
|
||||
"nc-webhook renamed (dir): %s -> %s : %s",
|
||||
old_abs, new_abs, result,
|
||||
)
|
||||
return {
|
||||
"status": "applied",
|
||||
"action": "rename_subtree",
|
||||
"from": old_abs,
|
||||
"to": new_abs,
|
||||
**result,
|
||||
}
|
||||
|
||||
# File rename (existing logic).
|
||||
if Path(old_abs).suffix.lower() in supported:
|
||||
await handle_file_deletion(old_abs)
|
||||
if new_abs and Path(new_abs).suffix.lower() in supported:
|
||||
if Path(new_abs).suffix.lower() in supported:
|
||||
parent_dir = str(Path(new_abs).parent)
|
||||
source_root_id = await _source_root_for(parent_dir)
|
||||
if source_root_id is not None:
|
||||
|
||||
Reference in New Issue
Block a user