From 005380f75d8ac8596e6b27fe58818a00e6362568 Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Tue, 6 May 2025 13:32:48 +0530 Subject: [PATCH 1/9] refactor(recyclebin): move interface from Products.CMFPlone --- src/plone/base/interfaces/recyclebin.py | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/plone/base/interfaces/recyclebin.py diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py new file mode 100644 index 0000000..92bbcb4 --- /dev/null +++ b/src/plone/base/interfaces/recyclebin.py @@ -0,0 +1,116 @@ +"""Interfaces for the Plone Recycle Bin functionality.""" + +from zope import schema +from zope.interface import Interface + + +class IRecycleBinControlPanelSettings(Interface): + """Interface for recycle bin settings""" + + recycling_enabled = schema.Bool( + title="Enable the recycle bin", + description="Enable or disable the recycle bin feature.", + default=False, + ) + + retention_period = schema.Int( + title="Retention period", + description="Number of days to keep deleted items in the recycle bin. Set to '0' to disable automatic purging.", + default=30, + min=0, + ) + + maximum_size = schema.Int( + title="Maximum size", + description="Maximum size of the recycle bin in MB. When the total size of items in the recycle bin exceeds its maximum size, the oldest items in the recycle bin will be permanently purged.", + default=100, + min=10, + ) + + +class IRecycleBin(Interface): + """Interface for the recycle bin functionality""" + + def add_item(obj, original_container, original_path): + """Add deleted item to recycle bin + + Args: + obj: The object being deleted + original_container: The parent container before deletion + original_path: The full path to the object before deletion + + Returns: + The ID of the item in the recycle bin + """ + + def get_items(): + """Return all items in recycle bin + + Returns: + A list of dictionaries with information about deleted items + """ + + def get_item(item_id): + """Get a specific deleted item by ID + + Args: + item_id: The ID of the deleted item in the recycle bin + + Returns: + Dictionary with item information or None if not found + """ + + def restore_item(item_id, target_container=None): + """Restore item to original location or specified container + + Args: + item_id: The ID of the item in the recycle bin + target_container: Optional target container to restore to + (defaults to original container) + + Returns: + The restored object or None if restore failed + """ + + def purge_item(item_id): + """Permanently delete an item + + Args: + item_id: The ID of the item in the recycle bin + + Returns: + Boolean indicating success + """ + + def purge_expired_items(): + """Purge items that exceed the retention period + + Returns: + Number of items purged + """ + + def is_enabled(): + """Check if recycle bin is enabled in the registry settings + + Returns: + Boolean indicating whether recycle bin is enabled + """ + +class IRecycleBinForm(Interface): + """Schema for the recycle bin form""" + + selected_items = schema.List( + title="Selected Items", + description="Selected items for operations", + value_type=schema.TextLine(), + required=False, + ) + +class IRecycleBinItemForm(Interface): + """Schema for the recycle bin item form""" + + target_container = schema.TextLine( + title="Target container", + description="Path to container where the item should be restored (optional)", + required=False, + ) \ No newline at end of file From 6f8d4738f3d71cc9812812e846da3d4319425bfc Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Sun, 11 May 2025 12:08:19 +0530 Subject: [PATCH 2/9] lint --- src/plone/base/interfaces/recyclebin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index 92bbcb4..bc21701 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -96,6 +96,7 @@ def is_enabled(): Boolean indicating whether recycle bin is enabled """ + class IRecycleBinForm(Interface): """Schema for the recycle bin form""" @@ -106,6 +107,7 @@ class IRecycleBinForm(Interface): required=False, ) + class IRecycleBinItemForm(Interface): """Schema for the recycle bin item form""" @@ -113,4 +115,4 @@ class IRecycleBinItemForm(Interface): title="Target container", description="Path to container where the item should be restored (optional)", required=False, - ) \ No newline at end of file + ) From 835d025c02f1a726d84d6e82fcf5bc761d71668a Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Mon, 28 Jul 2025 18:37:23 +0530 Subject: [PATCH 3/9] changelog --- news/89.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/89.feature diff --git a/news/89.feature b/news/89.feature new file mode 100644 index 0000000..6fa4e5f --- /dev/null +++ b/news/89.feature @@ -0,0 +1 @@ +Adds interface for recyclebin functionality @rohnsha0 \ No newline at end of file From 73cf713dd30194c9a486c63718330e79de5c030a Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Sun, 21 Sep 2025 00:09:02 +0530 Subject: [PATCH 4/9] feat(recyclebin): add restore_to_initial_state option to IRecycleBinControlPanelSettings --- src/plone/base/interfaces/recyclebin.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index bc21701..4780817 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -11,6 +11,8 @@ class IRecycleBinControlPanelSettings(Interface): title="Enable the recycle bin", description="Enable or disable the recycle bin feature.", default=False, + required=False, + ) retention_period = schema.Int( @@ -27,6 +29,13 @@ class IRecycleBinControlPanelSettings(Interface): min=10, ) + restore_to_initial_state = schema.Bool( + title="Restore to initial workflow state", + description="When enabled, restored content will be set to its initial workflow state (usually 'draft') instead of the workflow state it was in when deleted.", + default=False, + required=False, + ) + class IRecycleBin(Interface): """Interface for the recycle bin functionality""" From abaefca5d40c04e44da670caae57e896c733ee46 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 18:44:23 +0000 Subject: [PATCH 5/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/plone/base/interfaces/recyclebin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index 4780817..6fa0099 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -12,7 +12,6 @@ class IRecycleBinControlPanelSettings(Interface): description="Enable or disable the recycle bin feature.", default=False, required=False, - ) retention_period = schema.Int( From 4ff27e89210f99dfb471cdc4513eeeb95c01545a Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Sun, 21 Sep 2025 00:39:26 +0530 Subject: [PATCH 6/9] fix(recyclebin): change target_container schema type to Choice for better container selection --- src/plone/base/interfaces/recyclebin.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index 6fa0099..9e9f335 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -119,8 +119,9 @@ class IRecycleBinForm(Interface): class IRecycleBinItemForm(Interface): """Schema for the recycle bin item form""" - target_container = schema.TextLine( + target_container = schema.Choice( title="Target container", - description="Path to container where the item should be restored (optional)", + description="Choose the container where the item should be restored when original location no longer exists", + vocabulary="plone.recyclebin.RestoreContainers", required=False, ) From be666cbff101251a10e1f0da9afac82944e24b15 Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Mon, 22 Sep 2025 09:22:21 +0530 Subject: [PATCH 7/9] fix(recyclebin): change target_container schema type to TextLine for improved path input --- src/plone/base/interfaces/recyclebin.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index 9e9f335..f1abbb4 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -119,9 +119,8 @@ class IRecycleBinForm(Interface): class IRecycleBinItemForm(Interface): """Schema for the recycle bin item form""" - target_container = schema.Choice( + target_container = schema.TextLine( title="Target container", - description="Choose the container where the item should be restored when original location no longer exists", - vocabulary="plone.recyclebin.RestoreContainers", + description="Enter the path to the container where the item should be restored (e.g., /folder1/subfolder)", required=False, ) From 6550420e157c5e57f27d2409071b19fc54cc8de3 Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Mon, 22 Sep 2025 09:25:31 +0530 Subject: [PATCH 8/9] fix(recyclebin): update string literals to use PloneMessageFactory for localization --- src/plone/base/interfaces/recyclebin.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index f1abbb4..7afad7c 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -1,5 +1,6 @@ """Interfaces for the Plone Recycle Bin functionality.""" +from plone.base import PloneMessageFactory as _ from zope import schema from zope.interface import Interface @@ -8,29 +9,29 @@ class IRecycleBinControlPanelSettings(Interface): """Interface for recycle bin settings""" recycling_enabled = schema.Bool( - title="Enable the recycle bin", - description="Enable or disable the recycle bin feature.", + title=_("Enable the recycle bin"), + description=_("Enable or disable the recycle bin feature."), default=False, required=False, ) retention_period = schema.Int( - title="Retention period", - description="Number of days to keep deleted items in the recycle bin. Set to '0' to disable automatic purging.", + title=_("Retention period"), + description=_("Number of days to keep deleted items in the recycle bin. Set to '0' to disable automatic purging."), default=30, min=0, ) maximum_size = schema.Int( - title="Maximum size", - description="Maximum size of the recycle bin in MB. When the total size of items in the recycle bin exceeds its maximum size, the oldest items in the recycle bin will be permanently purged.", + title=_("Maximum size"), + description=_("Maximum size of the recycle bin in MB. When the total size of items in the recycle bin exceeds its maximum size, the oldest items in the recycle bin will be permanently purged."), default=100, min=10, ) restore_to_initial_state = schema.Bool( - title="Restore to initial workflow state", - description="When enabled, restored content will be set to its initial workflow state (usually 'draft') instead of the workflow state it was in when deleted.", + title=_("Restore to initial workflow state"), + description=_("When enabled, restored content will be set to its initial workflow state (usually 'draft') instead of the workflow state it was in when deleted."), default=False, required=False, ) @@ -109,8 +110,8 @@ class IRecycleBinForm(Interface): """Schema for the recycle bin form""" selected_items = schema.List( - title="Selected Items", - description="Selected items for operations", + title=_("Selected Items"), + description=_("Selected items for operations"), value_type=schema.TextLine(), required=False, ) @@ -120,7 +121,7 @@ class IRecycleBinItemForm(Interface): """Schema for the recycle bin item form""" target_container = schema.TextLine( - title="Target container", - description="Enter the path to the container where the item should be restored (e.g., /folder1/subfolder)", + title=_("Target container"), + description=_("Enter the path to the container where the item should be restored (e.g., /folder1/subfolder)"), required=False, ) From 1ac980739f58f008006849c648c122b0f3460495 Mon Sep 17 00:00:00 2001 From: Rohan Shaw Date: Mon, 22 Sep 2025 09:30:10 +0530 Subject: [PATCH 9/9] refactor(recyclebin): remove IRecycleBinForm and IRecycleBinItemForm back to CMFPlone --- src/plone/base/interfaces/recyclebin.py | 33 +++++++------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/plone/base/interfaces/recyclebin.py b/src/plone/base/interfaces/recyclebin.py index 7afad7c..ec54cab 100644 --- a/src/plone/base/interfaces/recyclebin.py +++ b/src/plone/base/interfaces/recyclebin.py @@ -17,21 +17,27 @@ class IRecycleBinControlPanelSettings(Interface): retention_period = schema.Int( title=_("Retention period"), - description=_("Number of days to keep deleted items in the recycle bin. Set to '0' to disable automatic purging."), + description=_( + "Number of days to keep deleted items in the recycle bin. Set to '0' to disable automatic purging." + ), default=30, min=0, ) maximum_size = schema.Int( title=_("Maximum size"), - description=_("Maximum size of the recycle bin in MB. When the total size of items in the recycle bin exceeds its maximum size, the oldest items in the recycle bin will be permanently purged."), + description=_( + "Maximum size of the recycle bin in MB. When the total size of items in the recycle bin exceeds its maximum size, the oldest items in the recycle bin will be permanently purged." + ), default=100, min=10, ) restore_to_initial_state = schema.Bool( title=_("Restore to initial workflow state"), - description=_("When enabled, restored content will be set to its initial workflow state (usually 'draft') instead of the workflow state it was in when deleted."), + description=_( + "When enabled, restored content will be set to its initial workflow state (usually 'draft') instead of the workflow state it was in when deleted." + ), default=False, required=False, ) @@ -104,24 +110,3 @@ def is_enabled(): Returns: Boolean indicating whether recycle bin is enabled """ - - -class IRecycleBinForm(Interface): - """Schema for the recycle bin form""" - - selected_items = schema.List( - title=_("Selected Items"), - description=_("Selected items for operations"), - value_type=schema.TextLine(), - required=False, - ) - - -class IRecycleBinItemForm(Interface): - """Schema for the recycle bin item form""" - - target_container = schema.TextLine( - title=_("Target container"), - description=_("Enter the path to the container where the item should be restored (e.g., /folder1/subfolder)"), - required=False, - )