Skip to content

Commit

Permalink
feat: Add lang auto tagging for v2 library blocks (openedx#34056)
Browse files Browse the repository at this point in the history
  • Loading branch information
yusuf-musleh authored Jan 23, 2024
1 parent eaec617 commit 2323b3b
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 5 deletions.
57 changes: 54 additions & 3 deletions openedx/core/djangoapps/content_tagging/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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}")
46 changes: 46 additions & 0 deletions openedx/core/djangoapps/content_tagging/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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
Expand Down Expand Up @@ -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
70 changes: 68 additions & 2 deletions openedx/core/djangoapps/content_tagging/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@

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

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
Expand Down Expand Up @@ -51,7 +55,12 @@ def setUp(self):

@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
"""
Expand Down Expand Up @@ -237,3 +246,60 @@ def test_waffle_disabled_create_delete_xblock(self):

# 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)

0 comments on commit 2323b3b

Please sign in to comment.