From 3da44d516361a14a7004292ee83a14504cb25412 Mon Sep 17 00:00:00 2001
From: Yusuf Musleh <yusuf@opencraft.com>
Date: Mon, 26 Aug 2024 07:42:19 +0300
Subject: [PATCH] feat: Add events emitting for Collections

---
 docs/hooks/events.rst                         | 12 ++++
 .../core/djangoapps/content_libraries/apps.py |  1 +
 .../content_libraries/collections/__init__.py |  0
 .../content_libraries/collections/handlers.py | 57 +++++++++++++++++++
 .../collections/rest_api/v1/views.py          | 26 +++++++++
 requirements/edx/base.txt                     |  2 +-
 requirements/edx/development.txt              |  2 +-
 requirements/edx/doc.txt                      |  2 +-
 requirements/edx/kernel.in                    |  4 +-
 requirements/edx/testing.txt                  |  2 +-
 10 files changed, 103 insertions(+), 5 deletions(-)
 create mode 100644 openedx/core/djangoapps/content_libraries/collections/__init__.py
 create mode 100644 openedx/core/djangoapps/content_libraries/collections/handlers.py

diff --git a/docs/hooks/events.rst b/docs/hooks/events.rst
index 7f9584c9e8e1..2bceee5050ea 100644
--- a/docs/hooks/events.rst
+++ b/docs/hooks/events.rst
@@ -247,3 +247,15 @@ Content Authoring Events
    * - `CONTENT_OBJECT_TAGS_CHANGED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L207>`_
      - org.openedx.content_authoring.content.object.tags.changed.v1
      - 2024-03-31
+
+   * - `LIBRARY_COLLECTION_CREATED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L219>`_
+     - org.openedx.content_authoring.content.library.collection.created.v1
+     - 2024-08-23
+
+   * - `LIBRARY_COLLECTION_UPDATED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L230>`_
+     - org.openedx.content_authoring.content.library.collection.updated.v1
+     - 2024-08-23
+
+   * - `LIBRARY_COLLECTION_DELETED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L241>`_
+     - org.openedx.content_authoring.content.library.collection.deleted.v1
+     - 2024-08-23
diff --git a/openedx/core/djangoapps/content_libraries/apps.py b/openedx/core/djangoapps/content_libraries/apps.py
index 52c3e5179721..aea920714ce0 100644
--- a/openedx/core/djangoapps/content_libraries/apps.py
+++ b/openedx/core/djangoapps/content_libraries/apps.py
@@ -37,3 +37,4 @@ def ready(self):
         Import signal handler's module to ensure they are registered.
         """
         from . import signal_handlers  # pylint: disable=unused-import
+        from .collections import handlers  # pylint: disable=unused-import
diff --git a/openedx/core/djangoapps/content_libraries/collections/__init__.py b/openedx/core/djangoapps/content_libraries/collections/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/openedx/core/djangoapps/content_libraries/collections/handlers.py b/openedx/core/djangoapps/content_libraries/collections/handlers.py
new file mode 100644
index 000000000000..c2c67ad403e5
--- /dev/null
+++ b/openedx/core/djangoapps/content_libraries/collections/handlers.py
@@ -0,0 +1,57 @@
+"""
+Signal handlers for Content Library Collections.
+"""
+
+import logging
+
+from django.dispatch import receiver
+from openedx_events.content_authoring.data import LibraryCollectionData
+from openedx_events.content_authoring.signals import (
+    LIBRARY_COLLECTION_CREATED,
+    LIBRARY_COLLECTION_UPDATED,
+    LIBRARY_COLLECTION_DELETED,
+)
+
+
+log = logging.getLogger(__name__)
+
+
+@receiver(LIBRARY_COLLECTION_CREATED)
+def library_collection_created_handler(**kwargs):
+    """
+    Content Library Collection Created signal handler
+    """
+    library_collection_data = kwargs.get("library_collection", None)
+    if not library_collection_data or not isinstance(library_collection_data, LibraryCollectionData):
+        log.error("Received null or incorrect data for event")
+        return
+
+    log.info("Received Collection Created Signal")
+
+    # TODO: Implement handler logic
+
+
+@receiver(LIBRARY_COLLECTION_UPDATED)
+def library_collection_updated_handler(**kwargs):
+    """
+    Content Library Collection Updated signal handler
+    """
+    library_collection_data = kwargs.get("library_collection", None)
+    if not library_collection_data or not isinstance(library_collection_data, LibraryCollectionData):
+        log.error("Received null or incorrect data for event")
+        return
+
+    log.info("Received Collection Updated Signal")
+
+
+@receiver(LIBRARY_COLLECTION_DELETED)
+def library_collection_deleted_handler(**kwargs):
+    """
+    Content Library Collection Deleted signal handler
+    """
+    library_collection_data = kwargs.get("library_collection", None)
+    if not library_collection_data or not isinstance(library_collection_data, LibraryCollectionData):
+        log.error("Received null or incorrect data for event")
+        return
+
+    log.info("Received Collection Deleted Signal")
diff --git a/openedx/core/djangoapps/content_libraries/collections/rest_api/v1/views.py b/openedx/core/djangoapps/content_libraries/collections/rest_api/v1/views.py
index 2c4df17e6d08..b20c00a48c96 100644
--- a/openedx/core/djangoapps/content_libraries/collections/rest_api/v1/views.py
+++ b/openedx/core/djangoapps/content_libraries/collections/rest_api/v1/views.py
@@ -12,6 +12,12 @@
 
 from opaque_keys.edx.locator import LibraryLocatorV2
 
+from openedx_events.content_authoring.data import LibraryCollectionData
+from openedx_events.content_authoring.signals import (
+    LIBRARY_COLLECTION_CREATED,
+    LIBRARY_COLLECTION_UPDATED,
+)
+
 from openedx.core.djangoapps.content_libraries import api, permissions
 from openedx.core.djangoapps.content_libraries.serializers import (
     ContentLibraryCollectionSerializer,
@@ -104,6 +110,15 @@ def create(self, request, lib_key_str):
             create_serializer.validated_data["description"]
         )
         serializer = self.get_serializer(collection)
+
+        # Emit event for library content collection creation
+        LIBRARY_COLLECTION_CREATED.send_event(
+            library_collection=LibraryCollectionData(
+                library_key=library_key,
+                collection_id=collection.id
+            )
+        )
+
         return Response(serializer.data)
 
     def partial_update(self, request, lib_key_str, pk=None):
@@ -126,6 +141,15 @@ def partial_update(self, request, lib_key_str, pk=None):
         update_serializer.is_valid(raise_exception=True)
         updated_collection = authoring_api.update_collection(pk, **update_serializer.validated_data)
         serializer = self.get_serializer(updated_collection)
+
+        # Emit event for library content collection updated
+        LIBRARY_COLLECTION_UPDATED.send_event(
+            library_collection=LibraryCollectionData(
+                library_key=library_key,
+                collection_id=collection.id
+            )
+        )
+
         return Response(serializer.data)
 
     def destroy(self, request, lib_key_str, pk=None):
@@ -134,4 +158,6 @@ def destroy(self, request, lib_key_str, pk=None):
 
         Note: (currently not allowed)
         """
+        # TODO: Implement the deletion logic and emit event signal
+
         return Response(None, status=HTTP_405_METHOD_NOT_ALLOWED)
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index 27de7847f284..107ed6a79018 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -811,7 +811,7 @@ openedx-django-require==2.1.0
     # via -r requirements/edx/kernel.in
 openedx-django-wiki==2.1.0
     # via -r requirements/edx/kernel.in
-openedx-events==9.11.0
+openedx-events @ git+https://github.com/open-craft/openedx-events.git@8101eb46d15717e7d5390af0901b8314a2c7da25
     # via
     #   -r requirements/edx/kernel.in
     #   edx-event-bus-kafka
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index 0bdc8144ee71..cefdd9b330ce 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -1358,7 +1358,7 @@ openedx-django-wiki==2.1.0
     # via
     #   -r requirements/edx/doc.txt
     #   -r requirements/edx/testing.txt
-openedx-events==9.11.0
+openedx-events @ git+https://github.com/open-craft/openedx-events.git@8101eb46d15717e7d5390af0901b8314a2c7da25
     # via
     #   -r requirements/edx/doc.txt
     #   -r requirements/edx/testing.txt
diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt
index 91b30d81df6d..91313a627e48 100644
--- a/requirements/edx/doc.txt
+++ b/requirements/edx/doc.txt
@@ -970,7 +970,7 @@ openedx-django-require==2.1.0
     # via -r requirements/edx/base.txt
 openedx-django-wiki==2.1.0
     # via -r requirements/edx/base.txt
-openedx-events==9.11.0
+openedx-events @ git+https://github.com/open-craft/openedx-events.git@8101eb46d15717e7d5390af0901b8314a2c7da25
     # via
     #   -r requirements/edx/base.txt
     #   edx-event-bus-kafka
diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in
index a5b510742ac7..5154dc293efa 100644
--- a/requirements/edx/kernel.in
+++ b/requirements/edx/kernel.in
@@ -117,7 +117,9 @@ olxcleaner
 openedx-atlas                       # CLI tool to manage translations
 openedx-calc                        # Library supporting mathematical calculations for Open edX
 openedx-django-require
-openedx-events                      # Open edX Events from Hooks Extension Framework (OEP-50)
+# openedx-events                      # Open edX Events from Hooks Extension Framework (OEP-50)
+# TODO: Remove this once new version released
+openedx-events @ git+https://github.com/open-craft/openedx-events.git@8101eb46d15717e7d5390af0901b8314a2c7da25
 openedx-filters                     # Open edX Filters from Hooks Extension Framework (OEP-50)
 openedx-learning                    # Open edX Learning core (experimental)
 openedx-mongodbproxy
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 2092c9354834..04b85af47b80 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -1021,7 +1021,7 @@ openedx-django-require==2.1.0
     # via -r requirements/edx/base.txt
 openedx-django-wiki==2.1.0
     # via -r requirements/edx/base.txt
-openedx-events==9.11.0
+openedx-events @ git+https://github.com/open-craft/openedx-events.git@8101eb46d15717e7d5390af0901b8314a2c7da25
     # via
     #   -r requirements/edx/base.txt
     #   edx-event-bus-kafka