diff --git a/openedx/core/djangoapps/content_libraries/api.py b/openedx/core/djangoapps/content_libraries/api.py index ebd25f54ddda..26e7c652d983 100644 --- a/openedx/core/djangoapps/content_libraries/api.py +++ b/openedx/core/djangoapps/content_libraries/api.py @@ -134,6 +134,7 @@ from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError +from openedx_tagging.core.tagging import api as tagging_api from . import tasks @@ -234,6 +235,7 @@ class LibraryXBlockMetadata: def_key = attr.ib(type=BundleDefinitionLocator) display_name = attr.ib("") has_unpublished_changes = attr.ib(False) + tags_count = attr.ib(0) @attr.s @@ -636,6 +638,15 @@ def delete_library(library_key): raise +def _get_library_component_tags_count(library_key) -> dict: + """ + Get the count of tags that are applied to each component in this library, as a dict. + """ + # Create a pattern to match the IDs of the library components, e.g. "lb:org:id*" + library_key_pattern = str(library_key).replace("lib:", "lb:", 1) + "*" + return tagging_api.get_object_tag_counts(library_key_pattern, count_implicit=True) + + def get_library_blocks(library_key, text_search=None, block_types=None) -> list[LibraryXBlockMetadata]: """ Get the list of top-level XBlocks in the specified library. @@ -646,6 +657,7 @@ def get_library_blocks(library_key, text_search=None, block_types=None) -> list[ ref = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined] lib_bundle = LibraryBundle(library_key, ref.bundle_uuid, draft_name=DRAFT_NAME) usages = lib_bundle.get_top_level_usages() + library_component_tags_count = _get_library_component_tags_count(library_key) for usage_key in usages: # For top-level definitions, we can go from definition key to usage key using the following, but this would @@ -663,6 +675,7 @@ def get_library_blocks(library_key, text_search=None, block_types=None) -> list[ "def_key": def_key, "display_name": display_name, "has_unpublished_changes": lib_bundle.does_definition_have_unpublished_changes(def_key), + "tags_count": library_component_tags_count.get(str(usage_key), 0), }) return [ @@ -671,6 +684,7 @@ def get_library_blocks(library_key, text_search=None, block_types=None) -> list[ def_key=item['def_key'], display_name=item['display_name'], has_unpublished_changes=item['has_unpublished_changes'], + tags_count=item['tags_count'] ) for item in metadata ] diff --git a/openedx/core/djangoapps/content_libraries/serializers.py b/openedx/core/djangoapps/content_libraries/serializers.py index 65df9174cbc4..800c8cb10585 100644 --- a/openedx/core/djangoapps/content_libraries/serializers.py +++ b/openedx/core/djangoapps/content_libraries/serializers.py @@ -117,6 +117,7 @@ class LibraryXBlockMetadataSerializer(serializers.Serializer): # When creating a new XBlock in a library, the slug becomes the ID part of # the definition key and usage key: slug = serializers.CharField(write_only=True) + tags_count = serializers.IntegerField(read_only=True) class LibraryXBlockTypeSerializer(serializers.Serializer): diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 6b7163fe9ed6..64eb54039bd4 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -103,7 +103,7 @@ libsass==0.10.0 click==8.1.6 # pinning this version to avoid updates while the library is being developed -openedx-learning==0.4.1 +openedx-learning==0.4.2 # Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise. openai<=0.28.1 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 9337c1c844cd..76c33bf67fd9 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -779,7 +779,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/kernel.in # lti-consumer-xblock -openedx-learning==0.4.1 +openedx-learning==0.4.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index bddf95f8079a..9381e2bd4aa2 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1311,7 +1311,7 @@ openedx-filters==1.6.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # lti-consumer-xblock -openedx-learning==0.4.1 +openedx-learning==0.4.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 7df0c83c85f9..a17007f812f1 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -921,7 +921,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock -openedx-learning==0.4.1 +openedx-learning==0.4.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 420953249426..bd7920e1c549 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -981,7 +981,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock -openedx-learning==0.4.1 +openedx-learning==0.4.2 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt