feat: Add lang auto tagging for v2 library blocks (#34056)
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user