feat: Add lang auto tagging for v2 library blocks (#34056)

This commit is contained in:
Yusuf Musleh
2024-01-23 21:00:40 +03:00
committed by GitHub
parent eaec617a4b
commit 2323b3b21a
3 changed files with 168 additions and 5 deletions

View File

@@ -2,17 +2,32 @@
Automatic tagging of content
"""
import crum
import logging
from django.dispatch import receiver
from openedx_events.content_authoring.data import CourseData, XBlockData
from openedx_events.content_authoring.signals import COURSE_CREATED, XBLOCK_CREATED, XBLOCK_DELETED, XBLOCK_UPDATED
from openedx_events.content_authoring.data import (
CourseData,
XBlockData,
LibraryBlockData,
)
from openedx_events.content_authoring.signals import (
COURSE_CREATED,
XBLOCK_CREATED,
XBLOCK_DELETED,
XBLOCK_UPDATED,
LIBRARY_BLOCK_CREATED,
LIBRARY_BLOCK_UPDATED,
LIBRARY_BLOCK_DELETED,
)
from .tasks import delete_course_tags
from .tasks import (
delete_xblock_tags,
update_course_tags,
update_xblock_tags
update_xblock_tags,
update_library_block_tags,
delete_library_block_tags,
)
from .toggles import CONTENT_TAGGING_AUTO
@@ -74,3 +89,39 @@ def delete_tag_xblock(**kwargs):
delete_course_tags.delay(str(xblock_info.usage_key.course_key))
delete_xblock_tags.delay(str(xblock_info.usage_key))
@receiver(LIBRARY_BLOCK_CREATED)
@receiver(LIBRARY_BLOCK_UPDATED)
def auto_tag_library_block(**kwargs):
"""
Automatically tag Library Blocks based on metadata
"""
if not CONTENT_TAGGING_AUTO.is_enabled():
return
library_block_data = kwargs.get("library_block", None)
if not library_block_data or not isinstance(library_block_data, LibraryBlockData):
log.error("Received null or incorrect data for event")
return
current_request = crum.get_current_request()
update_library_block_tags.delay(
str(library_block_data.usage_key), current_request.LANGUAGE_CODE
)
@receiver(LIBRARY_BLOCK_DELETED)
def delete_tag_library_block(**kwargs):
"""
Delete tags associated with a Library XBlock whenever the block is deleted.
"""
library_block_data = kwargs.get("library_block", None)
if not library_block_data or not isinstance(library_block_data, LibraryBlockData):
log.error("Received null or incorrect data for event")
return
try:
delete_library_block_tags(str(library_block_data.usage_key))
except Exception as err: # pylint: disable=broad-except
log.error(f"Failed to delete library block tags: {err}")

View File

@@ -11,6 +11,7 @@ from django.conf import settings
from django.contrib.auth import get_user_model
from edx_django_utils.monitoring import set_code_owner_attribute
from opaque_keys.edx.keys import LearningContextKey, UsageKey
from opaque_keys.edx.locator import LibraryUsageLocatorV2
from openedx_tagging.core.tagging.models import Taxonomy
from xmodule.modulestore.django import modulestore
@@ -152,3 +153,48 @@ def delete_xblock_tags(usage_key_str: str) -> bool:
except Exception as e: # pylint: disable=broad-except
log.error("Error deleting tags for XBlock with id: %s. %s", usage_key, e)
return False
@shared_task(base=LoggedTask)
@set_code_owner_attribute
def update_library_block_tags(usage_key_str: str, language_code: str) -> bool:
"""
Updates the automatically-managed tags for a content library block
whenever it is created/updated
Params:
usage_key_str (str): identifier of the Library Block
langauge_code (str): the preferred language code of the user
"""
try:
usage_key = LibraryUsageLocatorV2.from_string(usage_key_str)
log.info("Updating tags for Library Block with id: %s", usage_key)
_set_initial_language_tag(usage_key, language_code)
return True
except Exception as e: # pylint: disable=broad-except
log.error("Error updating tags for XBlock with id: %s. %s", usage_key, e)
return False
@shared_task(base=LoggedTask)
@set_code_owner_attribute
def delete_library_block_tags(usage_key_str: str) -> bool:
"""
Delete the tags for a Library Block (when the Library Block itself is deleted).
Params:
usage_key_str (str): identifier of the Library Block
"""
try:
usage_key = LibraryUsageLocatorV2.from_string(usage_key_str)
log.info("Deleting tags for Library Block with id: %s", usage_key)
_delete_tags(usage_key)
return True
except Exception as e: # pylint: disable=broad-except
log.error("Error deleting tags for Library Block with id: %s. %s", usage_key, e)
return False

View File

@@ -5,7 +5,8 @@ from __future__ import annotations
from unittest.mock import patch
from django.test import override_settings
from django.test import override_settings, LiveServerTestCase
from django.http import HttpRequest
from edx_toggles.toggles.testutils import override_waffle_flag
from openedx_tagging.core.tagging.models import Tag, Taxonomy
from organizations.models import Organization
@@ -13,6 +14,9 @@ from organizations.models import Organization
from common.djangoapps.student.tests.factories import UserFactory
from openedx.core.djangolib.testing.utils import skip_unless_cms
from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase
from openedx.core.lib.blockstore_api import create_collection
from openedx.core.djangoapps.content_libraries.api import create_library, create_library_block, delete_library_block
from openedx.core.lib.blockstore_api.tests.base import BlockstoreAppTestMixin
from .. import api
from ..models.base import TaxonomyOrg
@@ -51,7 +55,12 @@ class LanguageTaxonomyTestMixin:
@skip_unless_cms # Auto-tagging is only available in the CMS
@override_waffle_flag(CONTENT_TAGGING_AUTO, active=True)
class TestAutoTagging(LanguageTaxonomyTestMixin, ModuleStoreTestCase): # type: ignore[misc]
class TestAutoTagging( # type: ignore[misc]
LanguageTaxonomyTestMixin,
ModuleStoreTestCase,
BlockstoreAppTestMixin,
LiveServerTestCase
):
"""
Test if the Course and XBlock tags are automatically created
"""
@@ -237,3 +246,60 @@ class TestAutoTagging(LanguageTaxonomyTestMixin, ModuleStoreTestCase): # type:
# Still no tags
assert self._check_tag(usage_key_str, LANGUAGE_TAXONOMY_ID, None)
def test_create_delete_library_block(self):
# Create collection and library
collection = create_collection("Test library collection")
library = create_library(
collection_uuid=collection.uuid,
org=self.orgA,
slug="lib_a",
title="Library Org A",
description="This is a library from Org A",
)
fake_request = HttpRequest()
fake_request.LANGUAGE_CODE = "pt-br"
with patch('crum.get_current_request', return_value=fake_request):
# Create Library Block
library_block = create_library_block(library.key, "problem", "Problem1")
usage_key_str = str(library_block.usage_key)
# Check if the tags are created in the Library Block with the user's preferred language
assert self._check_tag(usage_key_str, LANGUAGE_TAXONOMY_ID, 'Português (Brasil)')
# Delete the XBlock
delete_library_block(library_block.usage_key)
# Check if the tags are deleted
assert self._check_tag(usage_key_str, LANGUAGE_TAXONOMY_ID, None)
@override_waffle_flag(CONTENT_TAGGING_AUTO, active=False)
def test_waffle_disabled_create_delete_library_block(self):
# Create collection and library
collection = create_collection("Test library collection 2")
library = create_library(
collection_uuid=collection.uuid,
org=self.orgA,
slug="lib_a2",
title="Library Org A 2",
description="This is a library from Org A 2",
)
fake_request = HttpRequest()
fake_request.LANGUAGE_CODE = "pt-br"
with patch('crum.get_current_request', return_value=fake_request):
# Create Library Block
library_block = create_library_block(library.key, "problem", "Problem2")
usage_key_str = str(library_block.usage_key)
# No tags created
assert self._check_tag(usage_key_str, LANGUAGE_TAXONOMY_ID, None)
# Delete the XBlock
delete_library_block(library_block.usage_key)
# Still no tags
assert self._check_tag(usage_key_str, LANGUAGE_TAXONOMY_ID, None)