chore: Switch to new openedx-learning import paths (#38004)
Upgrades openedx-learning from 0.31.0 to 0.32.0, incorporating a major openedx-learning Python API restructuring: ca0b3eb
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
import django.db.migrations.operations.special
|
||||
import django.db.models.deletion
|
||||
import opaque_keys.edx.django.models
|
||||
import openedx_learning.lib.fields
|
||||
import openedx_learning.lib.validators
|
||||
import openedx_django_lib.fields
|
||||
import openedx_django_lib.validators
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
@@ -107,8 +107,8 @@ class Migration(migrations.Migration):
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('context_key', opaque_keys.edx.django.models.CourseKeyField(help_text='Linking status for course context key', max_length=255, unique=True)),
|
||||
('status', models.CharField(choices=[('pending', 'Pending'), ('processing', 'Processing'), ('failed', 'Failed'), ('completed', 'Completed')], help_text='Status of links in given learning context/course.', max_length=20)),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learning Context Links status',
|
||||
@@ -121,13 +121,13 @@ class Migration(migrations.Migration):
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')),
|
||||
('upstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(help_text='Upstream block usage key, this value cannot be null and useful to track upstream library blocks that do not exist yet', max_length=255)),
|
||||
('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)),
|
||||
('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)),
|
||||
('version_synced', models.IntegerField()),
|
||||
('version_declined', models.IntegerField(blank=True, null=True)),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('upstream_block', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='openedx_content.component')),
|
||||
],
|
||||
options={
|
||||
@@ -140,13 +140,13 @@ class Migration(migrations.Migration):
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')),
|
||||
('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)),
|
||||
('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)),
|
||||
('version_synced', models.IntegerField()),
|
||||
('version_declined', models.IntegerField(blank=True, null=True)),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('upstream_container_key', opaque_keys.edx.django.models.ContainerKeyField(help_text='Upstream block key (e.g. lct:...), this value cannot be null and is useful to track upstream library blocks that do not exist yet or were deleted.', max_length=255)),
|
||||
('upstream_container', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='openedx_content.container')),
|
||||
],
|
||||
|
||||
@@ -4,8 +4,8 @@ import uuid
|
||||
|
||||
import django.db.models.deletion
|
||||
import opaque_keys.edx.django.models
|
||||
import openedx_learning.lib.fields
|
||||
import openedx_learning.lib.validators
|
||||
import openedx_django_lib.fields
|
||||
import openedx_django_lib.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ class Migration(migrations.Migration):
|
||||
max_length=20,
|
||||
),
|
||||
),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Learning Context Links status',
|
||||
@@ -61,7 +61,7 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
(
|
||||
'upstream_context_key',
|
||||
openedx_learning.lib.fields.MultiCollationCharField(
|
||||
openedx_django_lib.fields.MultiCollationCharField(
|
||||
db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'},
|
||||
db_index=True,
|
||||
help_text='Upstream context key i.e., learning_package/library key',
|
||||
@@ -72,8 +72,8 @@ class Migration(migrations.Migration):
|
||||
('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)),
|
||||
('version_synced', models.IntegerField()),
|
||||
('version_declined', models.IntegerField(blank=True, null=True)),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
(
|
||||
'upstream_block',
|
||||
models.ForeignKey(
|
||||
|
||||
@@ -3,8 +3,8 @@ import uuid
|
||||
|
||||
import django.db.models.deletion
|
||||
import opaque_keys.edx.django.models
|
||||
import openedx_learning.lib.fields
|
||||
import openedx_learning.lib.validators
|
||||
import openedx_django_lib.fields
|
||||
import openedx_django_lib.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ class Migration(migrations.Migration):
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='UUID')),
|
||||
('upstream_context_key', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('upstream_context_key', openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}, db_index=True, help_text='Upstream context key i.e., learning_package/library key', max_length=500)),
|
||||
('downstream_usage_key', opaque_keys.edx.django.models.UsageKeyField(max_length=255, unique=True)),
|
||||
('downstream_context_key', opaque_keys.edx.django.models.CourseKeyField(db_index=True, max_length=255)),
|
||||
('version_synced', models.IntegerField()),
|
||||
('version_declined', models.IntegerField(blank=True, null=True)),
|
||||
('created', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_learning.lib.validators.validate_utc_datetime])),
|
||||
('created', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('updated', models.DateTimeField(validators=[openedx_django_lib.validators.validate_utc_datetime])),
|
||||
('upstream_container_key', opaque_keys.edx.django.models.ContainerKeyField(help_text='Upstream block key (e.g. lct:...), this value cannot be null and is useful to track upstream library blocks that do not exist yet or were deleted.', max_length=255)),
|
||||
('upstream_container', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='links', to='oel_publishing.container')),
|
||||
],
|
||||
|
||||
@@ -15,9 +15,9 @@ from django.utils.translation import gettext_lazy as _
|
||||
from opaque_keys.edx.django.models import ContainerKeyField, CourseKeyField, UsageKeyField
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import LibraryContainerLocator
|
||||
from openedx_learning.api.authoring import get_published_version
|
||||
from openedx_learning.api.authoring_models import Component, Container
|
||||
from openedx_learning.lib.fields import (
|
||||
from openedx_content.api import get_published_version
|
||||
from openedx_content.models_api import Component, Container
|
||||
from openedx_django_lib.fields import (
|
||||
immutable_uuid_field,
|
||||
key_field,
|
||||
manual_date_time_field,
|
||||
|
||||
@@ -32,13 +32,13 @@ class APIHeartBeatView(DeveloperErrorViewMixin, APIView):
|
||||
**Response Values**
|
||||
|
||||
If the request is successful, an HTTP 200 "OK" response is returned.
|
||||
The HTTP 200 response contains a single dict with the "authoring_api_enabled" value "True".
|
||||
The HTTP 200 response contains a single dict with the "content_api_enabled" value "True".
|
||||
|
||||
**Example Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"authoring_api_enabled": "True"
|
||||
"content_api_enabled": "True"
|
||||
}
|
||||
```
|
||||
"""
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.conf import settings
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from organizations.tests.factories import OrganizationFactory
|
||||
from rest_framework import status
|
||||
|
||||
@@ -272,7 +272,7 @@ class HomePageLibrariesViewTest(LibraryTestCase):
|
||||
self.url = reverse("cms.djangoapps.contentstore:v1:libraries")
|
||||
# Create a collection to migrate this library to
|
||||
collection_key = "test-collection"
|
||||
authoring_api.create_collection(
|
||||
content_api.create_collection(
|
||||
learning_package_id=learning_package.id,
|
||||
key=collection_key,
|
||||
title="Test Collection",
|
||||
|
||||
@@ -13,7 +13,7 @@ from openedx_events.content_authoring.signals import (
|
||||
XBLOCK_UPDATED,
|
||||
)
|
||||
from openedx_events.tests.utils import OpenEdxEventsTestMixin
|
||||
from openedx_tagging.core.tagging.models import Tag
|
||||
from openedx_tagging.models import Tag
|
||||
from organizations.models import Organization
|
||||
from xmodule.modulestore.django import contentstore, modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, upload_file_to_course, ImmediateOnCommitMixin
|
||||
|
||||
@@ -11,8 +11,8 @@ from opaque_keys.edx.keys import UsageKey
|
||||
from opaque_keys.edx.locator import (
|
||||
LibraryLocatorV2, LibraryUsageLocatorV2, LibraryContainerLocator
|
||||
)
|
||||
from openedx_learning.api.authoring import get_draft_version, get_all_drafts
|
||||
from openedx_learning.api.authoring_models import (
|
||||
from openedx_content.api import get_draft_version, get_all_drafts
|
||||
from openedx_content.models_api import (
|
||||
PublishableEntityVersion, PublishableEntity, DraftChangeLogRecord
|
||||
)
|
||||
from xblock.plugin import PluginMissingError
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
|
||||
from celery.result import AsyncResult
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_learning.api.authoring import get_collection
|
||||
from openedx_content.api import get_collection
|
||||
|
||||
from openedx.core.types.user import AuthUser
|
||||
from openedx.core.djangoapps.content_libraries.api import get_library
|
||||
|
||||
@@ -11,7 +11,7 @@ from opaque_keys.edx.django.models import (
|
||||
LearningContextKeyField,
|
||||
UsageKeyField,
|
||||
)
|
||||
from openedx_learning.api.authoring_models import (
|
||||
from openedx_content.models_api import (
|
||||
Collection,
|
||||
DraftChangeLog,
|
||||
DraftChangeLogRecord,
|
||||
|
||||
@@ -5,7 +5,7 @@ Serializers for the Course to Library Import API.
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import LearningContextKey
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_learning.api.authoring_models import Collection
|
||||
from openedx_content.models_api import Collection
|
||||
from rest_framework import serializers
|
||||
from user_tasks.models import UserTaskStatus
|
||||
from user_tasks.serializers import StatusSerializer
|
||||
|
||||
@@ -30,8 +30,8 @@ from opaque_keys.edx.locator import (
|
||||
LibraryLocatorV2,
|
||||
LibraryUsageLocatorV2,
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import (
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import (
|
||||
Collection,
|
||||
Component,
|
||||
ComponentType,
|
||||
@@ -295,8 +295,8 @@ def _import_assets(migration: models.ModulestoreMigration) -> dict[str, int]:
|
||||
continue
|
||||
filename = os.path.basename(old_path)
|
||||
media_type_str = mimetypes.guess_type(filename)[0] or "application/octet-stream"
|
||||
media_type = authoring_api.get_or_create_media_type(media_type_str)
|
||||
content_by_filename[filename] = authoring_api.get_or_create_file_content(
|
||||
media_type = content_api.get_or_create_media_type(media_type_str)
|
||||
content_by_filename[filename] = content_api.get_or_create_file_content(
|
||||
migration.target_id,
|
||||
media_type.id,
|
||||
data=file_data,
|
||||
@@ -335,7 +335,7 @@ def _import_structure(
|
||||
tuple[Any, _MigratedNode]:
|
||||
A tuple containing:
|
||||
- The first element (`change_log`): the bulk draft change log generated by
|
||||
`authoring_api.bulk_draft_changes_for`, containing all the imported changes.
|
||||
`content_api.bulk_draft_changes_for`, containing all the imported changes.
|
||||
- The second element (`root_migrated_node`): a `_MigratedNode` object that
|
||||
represents the mapping between the legacy root node and its newly created
|
||||
Learning Core equivalent.
|
||||
@@ -345,12 +345,12 @@ def _import_structure(
|
||||
used_component_keys=set(
|
||||
LibraryUsageLocatorV2(target_library.key, block_type, block_id) # type: ignore[abstract]
|
||||
for block_type, block_id
|
||||
in authoring_api.get_components(migration.target.pk).values_list(
|
||||
in content_api.get_components(migration.target.pk).values_list(
|
||||
"component_type__name", "local_key"
|
||||
)
|
||||
),
|
||||
used_container_slugs=set(
|
||||
authoring_api.get_containers(
|
||||
content_api.get_containers(
|
||||
migration.target.pk
|
||||
).values_list("publishable_entity__key", flat=True)
|
||||
),
|
||||
@@ -369,7 +369,7 @@ def _import_structure(
|
||||
created_by=status.user_id,
|
||||
created_at=datetime.now(timezone.utc),
|
||||
)
|
||||
with authoring_api.bulk_draft_changes_for(migration.target.id) as change_log:
|
||||
with content_api.bulk_draft_changes_for(migration.target.id) as change_log:
|
||||
root_migrated_node = _migrate_node(
|
||||
context=migration_context,
|
||||
source_node=root_node,
|
||||
@@ -407,7 +407,7 @@ def _populate_collection(user_id: int, migration: models.ModulestoreMigration) -
|
||||
).values_list('target_id', flat=True)
|
||||
)
|
||||
if block_target_pks:
|
||||
authoring_api.add_to_collection(
|
||||
content_api.add_to_collection(
|
||||
learning_package_id=migration.target.pk,
|
||||
key=migration.target_collection.key,
|
||||
entities_qset=PublishableEntity.objects.filter(id__in=block_target_pks),
|
||||
@@ -693,7 +693,7 @@ def bulk_migrate_from_modulestore(
|
||||
if source_data.previous_migration:
|
||||
if previous_collection_slug := source_data.previous_migration.target_collection_slug:
|
||||
try:
|
||||
existing_collection_to_use = authoring_api.get_collection(
|
||||
existing_collection_to_use = content_api.get_collection(
|
||||
target_package.id, previous_collection_slug
|
||||
)
|
||||
except Collection.DoesNotExist:
|
||||
@@ -886,11 +886,11 @@ def _migrate_container(
|
||||
version_num=container.draft_version_num,
|
||||
), None
|
||||
|
||||
container_publishable_entity_version = authoring_api.create_next_container_version(
|
||||
container_publishable_entity_version = content_api.create_next_container_version(
|
||||
container.container_pk,
|
||||
title=title,
|
||||
entity_rows=[
|
||||
authoring_api.ContainerEntityRow(entity_pk=child.entity_id, version_pk=None)
|
||||
content_api.ContainerEntityRow(entity_pk=child.entity_id, version_pk=None)
|
||||
for child in children
|
||||
],
|
||||
created=context.created_at,
|
||||
@@ -924,7 +924,7 @@ def _migrate_component(
|
||||
(We assume that the destination is a library rather than some other future kind of learning
|
||||
package, but let's keep than an internal assumption.)
|
||||
"""
|
||||
component_type = authoring_api.get_or_create_component_type("xblock.v1", source_key.block_type)
|
||||
component_type = content_api.get_or_create_component_type("xblock.v1", source_key.block_type)
|
||||
|
||||
target_key = _get_distinct_target_usage_key(
|
||||
context,
|
||||
@@ -934,7 +934,7 @@ def _migrate_component(
|
||||
)
|
||||
|
||||
try:
|
||||
component = authoring_api.get_components(context.target_package_id).get(
|
||||
component = content_api.get_components(context.target_package_id).get(
|
||||
component_type=component_type,
|
||||
local_key=target_key.block_id,
|
||||
)
|
||||
@@ -954,7 +954,7 @@ def _migrate_component(
|
||||
except PluginMissingError as e:
|
||||
log.error(f"Block type not supported in {context.target_library_key}: {e}")
|
||||
return None, f"Invalid block type: {e}"
|
||||
component = authoring_api.create_component(
|
||||
component = content_api.create_component(
|
||||
context.target_package_id,
|
||||
component_type=component_type,
|
||||
local_key=target_key.block_id,
|
||||
@@ -974,7 +974,7 @@ def _migrate_component(
|
||||
if filename_no_ext not in olx:
|
||||
continue
|
||||
new_path = f"static/{filename}"
|
||||
authoring_api.create_component_version_content(
|
||||
content_api.create_component_version_content(
|
||||
component_version.pk, content_pk, key=new_path
|
||||
)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Test cases for the modulestore migrator API.
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
from opaque_keys.edx.locator import LibraryLocator, LibraryLocatorV2, CourseLocator
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from organizations.tests.factories import OrganizationFactory
|
||||
|
||||
from cms.djangoapps.modulestore_migrator import api
|
||||
@@ -224,7 +224,7 @@ class TestModulestoreMigratorAPI(ModuleStoreTestCase):
|
||||
user = UserFactory()
|
||||
|
||||
collection_key = "test-collection"
|
||||
authoring_api.create_collection(
|
||||
content_api.create_collection(
|
||||
learning_package_id=self.learning_package.id,
|
||||
key=collection_key,
|
||||
title="Test Collection",
|
||||
@@ -479,19 +479,19 @@ class TestModulestoreMigratorAPI(ModuleStoreTestCase):
|
||||
|
||||
# Lib 1 has Collection A and Collection B
|
||||
# Lib 2 has Collection C
|
||||
authoring_api.create_collection(
|
||||
content_api.create_collection(
|
||||
learning_package_id=self.learning_package.id,
|
||||
key="test-collection-1a",
|
||||
title="Test Collection A in Lib 1",
|
||||
created_by=user.id,
|
||||
)
|
||||
authoring_api.create_collection(
|
||||
content_api.create_collection(
|
||||
learning_package_id=self.learning_package.id,
|
||||
key="test-collection-1b",
|
||||
title="Test Collection B in Lib 1",
|
||||
created_by=user.id,
|
||||
)
|
||||
authoring_api.create_collection(
|
||||
content_api.create_collection(
|
||||
learning_package_id=self.learning_package_2.id,
|
||||
key="test-collection-2c",
|
||||
title="Test Collection C in Lib 2",
|
||||
|
||||
@@ -9,8 +9,8 @@ from django.utils import timezone
|
||||
from lxml import etree
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys.edx.locator import LibraryLocator, LibraryLocatorV2
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Collection, PublishableEntityVersion
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Collection, PublishableEntityVersion
|
||||
from organizations.tests.factories import OrganizationFactory
|
||||
from user_tasks.models import UserTaskArtifact
|
||||
from user_tasks.tasks import UserTaskStatus
|
||||
@@ -404,8 +404,8 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
source_key = self.course.id.make_usage_key("problem", "test_problem_with_image")
|
||||
olx = '<problem display_name="Test Problem"><p>See image: test_image.png</p></problem>'
|
||||
|
||||
media_type = authoring_api.get_or_create_media_type("image/png")
|
||||
test_content = authoring_api.get_or_create_file_content(
|
||||
media_type = content_api.get_or_create_media_type("image/png")
|
||||
test_content = content_api.get_or_create_file_content(
|
||||
self.learning_package.id,
|
||||
media_type.id,
|
||||
data=b"fake_image_data",
|
||||
@@ -637,14 +637,14 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
)
|
||||
olx = '<problem display_name="Test Problem"><p>See image: referenced.png</p></problem>'
|
||||
|
||||
media_type = authoring_api.get_or_create_media_type("image/png")
|
||||
referenced_content = authoring_api.get_or_create_file_content(
|
||||
media_type = content_api.get_or_create_media_type("image/png")
|
||||
referenced_content = content_api.get_or_create_file_content(
|
||||
self.learning_package.id,
|
||||
media_type.id,
|
||||
data=b"referenced_image_data",
|
||||
created=timezone.now(),
|
||||
)
|
||||
unreferenced_content = authoring_api.get_or_create_file_content(
|
||||
unreferenced_content = content_api.get_or_create_file_content(
|
||||
self.learning_package.id,
|
||||
media_type.id,
|
||||
data=b"unreferenced_image_data",
|
||||
@@ -711,32 +711,32 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
"""
|
||||
source_key = self.course.id.make_usage_key("vertical", "test_vertical")
|
||||
|
||||
child_component_1 = authoring_api.create_component(
|
||||
child_component_1 = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "problem"
|
||||
),
|
||||
local_key="child_problem_1",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
child_version_1 = authoring_api.create_next_component_version(
|
||||
child_version_1 = content_api.create_next_component_version(
|
||||
child_component_1.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
|
||||
child_component_2 = authoring_api.create_component(
|
||||
child_component_2 = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "html"
|
||||
),
|
||||
local_key="child_html_1",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
child_version_2 = authoring_api.create_next_component_version(
|
||||
child_version_2 = content_api.create_next_component_version(
|
||||
child_component_2.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
@@ -801,7 +801,7 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
container_version = result.containerversion
|
||||
self.assertEqual(container_version.title, f"Test {block_type.title()}")
|
||||
# The container is published
|
||||
self.assertFalse(authoring_api.contains_unpublished_changes(container_version.container.pk))
|
||||
self.assertFalse(content_api.contains_unpublished_changes(container_version.container.pk))
|
||||
|
||||
def test_migrate_container_same_title(self):
|
||||
"""
|
||||
@@ -899,16 +899,16 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
context = self._make_migration_context(repeat_handling_strategy=RepeatHandlingStrategy.Skip)
|
||||
children = []
|
||||
for i in range(3):
|
||||
child_component = authoring_api.create_component(
|
||||
child_component = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "problem"
|
||||
),
|
||||
local_key=f"child_problem_{i}",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
child_version = authoring_api.create_next_component_version(
|
||||
child_version = content_api.create_next_component_version(
|
||||
child_component.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
@@ -939,48 +939,48 @@ class TestMigrateFromModulestore(ModuleStoreTestCase):
|
||||
"""
|
||||
source_key = self.course.id.make_usage_key("vertical", "mixed_vertical")
|
||||
|
||||
problem_component = authoring_api.create_component(
|
||||
problem_component = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "problem"
|
||||
),
|
||||
local_key="mixed_problem",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
problem_version = authoring_api.create_next_component_version(
|
||||
problem_version = content_api.create_next_component_version(
|
||||
problem_component.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
|
||||
html_component = authoring_api.create_component(
|
||||
html_component = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "html"
|
||||
),
|
||||
local_key="mixed_html",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
html_version = authoring_api.create_next_component_version(
|
||||
html_version = content_api.create_next_component_version(
|
||||
html_component.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
|
||||
video_component = authoring_api.create_component(
|
||||
video_component = content_api.create_component(
|
||||
self.learning_package.id,
|
||||
component_type=authoring_api.get_or_create_component_type(
|
||||
component_type=content_api.get_or_create_component_type(
|
||||
"xblock.v1", "video"
|
||||
),
|
||||
local_key="mixed_video",
|
||||
created=timezone.now(),
|
||||
created_by=self.user.id,
|
||||
)
|
||||
video_version = authoring_api.create_next_component_version(
|
||||
video_version = content_api.create_next_component_version(
|
||||
video_component.pk,
|
||||
content_to_replace={},
|
||||
created=timezone.now(),
|
||||
|
||||
@@ -45,7 +45,7 @@ from corsheaders.defaults import default_headers as corsheaders_default_headers
|
||||
from datetime import timedelta
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from openedx_learning.api.django import openedx_learning_apps_to_install
|
||||
from openedx_content.settings_api import openedx_content_backcompat_apps_to_install
|
||||
|
||||
from openedx.envs.common import * # pylint: disable=wildcard-import
|
||||
|
||||
@@ -849,7 +849,7 @@ INSTALLED_APPS = [
|
||||
'drf_yasg',
|
||||
|
||||
# Tagging
|
||||
'openedx_tagging.core.tagging.apps.TaggingConfig',
|
||||
'openedx_tagging',
|
||||
'openedx.core.djangoapps.content_tagging',
|
||||
|
||||
# Search
|
||||
@@ -898,7 +898,9 @@ INSTALLED_APPS = [
|
||||
|
||||
'openedx_events',
|
||||
|
||||
*openedx_learning_apps_to_install(),
|
||||
# Core apps that power libraries
|
||||
"openedx_content",
|
||||
*openedx_content_backcompat_apps_to_install(),
|
||||
]
|
||||
|
||||
### Apps only installed in some instances
|
||||
|
||||
@@ -818,4 +818,3 @@ ZENDESK_GROUP_ID_MAPPING:
|
||||
ZENDESK_OAUTH_ACCESS_TOKEN: test_zendesk_access
|
||||
ZENDESK_URL: https://zendesk.com
|
||||
ZENDESK_USER: daemon@example.com
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ from enterprise.constants import (
|
||||
PROVISIONING_PENDING_ENTERPRISE_CUSTOMER_ADMIN_ROLE,
|
||||
DEFAULT_ENTERPRISE_ENROLLMENT_INTENTIONS_ROLE,
|
||||
)
|
||||
from openedx_learning.api.django import openedx_learning_apps_to_install
|
||||
from openedx_content.settings_api import openedx_content_backcompat_apps_to_install
|
||||
|
||||
from openedx.core.lib.derived import Derived
|
||||
from openedx.envs.common import * # pylint: disable=wildcard-import
|
||||
@@ -1950,7 +1950,7 @@ INSTALLED_APPS = [
|
||||
'lms.djangoapps.course_goals.apps.CourseGoalsConfig',
|
||||
|
||||
# Tagging
|
||||
'openedx_tagging.core.tagging.apps.TaggingConfig',
|
||||
'openedx_tagging',
|
||||
'openedx.core.djangoapps.content_tagging',
|
||||
|
||||
# Features
|
||||
@@ -2020,8 +2020,9 @@ INSTALLED_APPS = [
|
||||
|
||||
'openedx_events',
|
||||
|
||||
# Learning Core apps that power libraries
|
||||
*openedx_learning_apps_to_install(),
|
||||
# Core apps that power libraries
|
||||
"openedx_content",
|
||||
*openedx_content_backcompat_apps_to_install(),
|
||||
]
|
||||
|
||||
# Add LMS specific optional apps
|
||||
|
||||
@@ -25,7 +25,7 @@ from opaque_keys.edx.locator import (
|
||||
LibraryContainerLocator,
|
||||
LibraryLocatorV2,
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from rest_framework.request import Request
|
||||
|
||||
from common.djangoapps.student.role_helpers import get_course_roles
|
||||
@@ -556,7 +556,7 @@ def rebuild_index(status_cb: Callable[[str], None] | None = None, incremental=Fa
|
||||
|
||||
# To reduce memory usage on large instances, split up the Collections into pages of 100 collections:
|
||||
library = lib_api.get_library(lib_key)
|
||||
collections = authoring_api.get_collections(library.learning_package_id, enabled=True)
|
||||
collections = content_api.get_collections(library.learning_package_id, enabled=True)
|
||||
num_collections = collections.count()
|
||||
num_collections_done = 0
|
||||
status_cb(f"{num_collections_done}/{num_collections}. Now indexing collections in library {lib_key}")
|
||||
@@ -572,7 +572,7 @@ def rebuild_index(status_cb: Callable[[str], None] | None = None, incremental=Fa
|
||||
status_cb(f"{num_collections_done}/{num_collections} collections indexed for library {lib_key}")
|
||||
|
||||
# Similarly, batch process Containers (units, sections, etc) in pages of 100
|
||||
containers = authoring_api.get_containers(library.learning_package_id)
|
||||
containers = content_api.get_containers(library.learning_package_id)
|
||||
num_containers = containers.count()
|
||||
num_containers_done = 0
|
||||
status_cb(f"{num_containers_done}/{num_containers}. Now indexing containers in library {lib_key}")
|
||||
@@ -791,7 +791,7 @@ def update_library_components_collections(
|
||||
"""
|
||||
library_key = collection_key.lib_key
|
||||
library = lib_api.get_library(library_key)
|
||||
components = authoring_api.get_collection_components(
|
||||
components = content_api.get_collection_components(
|
||||
library.learning_package_id,
|
||||
collection_key.collection_id,
|
||||
)
|
||||
@@ -827,7 +827,7 @@ def update_library_containers_collections(
|
||||
"""
|
||||
library_key = collection_key.lib_key
|
||||
library = lib_api.get_library(library_key)
|
||||
containers = authoring_api.get_collection_containers(
|
||||
containers = content_api.get_collection_containers(
|
||||
library.learning_package_id,
|
||||
collection_key.collection_id,
|
||||
)
|
||||
|
||||
@@ -10,8 +10,8 @@ from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils.text import slugify
|
||||
from opaque_keys.edx.keys import ContainerKey, LearningContextKey, UsageKey, OpaqueKey
|
||||
from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Collection
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Collection
|
||||
from rest_framework.exceptions import NotFound
|
||||
|
||||
from openedx.core.djangoapps.content.search.models import SearchAccess
|
||||
@@ -446,7 +446,7 @@ def searchable_doc_collections(object_id: OpaqueKey) -> dict:
|
||||
try:
|
||||
if isinstance(object_id, UsageKey):
|
||||
component = lib_api.get_component_from_usage_key(object_id)
|
||||
collections = authoring_api.get_entity_collections(
|
||||
collections = content_api.get_entity_collections(
|
||||
component.learning_package_id,
|
||||
component.key,
|
||||
).values('key', 'title')
|
||||
@@ -543,11 +543,11 @@ def searchable_doc_for_collection(
|
||||
if collection:
|
||||
assert collection.key == collection_key.collection_id
|
||||
|
||||
draft_num_children = authoring_api.filter_publishable_entities(
|
||||
draft_num_children = content_api.filter_publishable_entities(
|
||||
collection.entities,
|
||||
has_draft=True,
|
||||
).count()
|
||||
published_num_children = authoring_api.filter_publishable_entities(
|
||||
published_num_children = content_api.filter_publishable_entities(
|
||||
collection.entities,
|
||||
has_published=True,
|
||||
).count()
|
||||
|
||||
@@ -15,7 +15,7 @@ import pytest
|
||||
from django.test import override_settings
|
||||
from freezegun import freeze_time
|
||||
from meilisearch.errors import MeilisearchApiError
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from organizations.tests.factories import OrganizationFactory
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
@@ -189,9 +189,9 @@ class TestSearchApi(ModuleStoreTestCase):
|
||||
tagging_api.add_tag_to_taxonomy(self.taxonomyB, "four")
|
||||
|
||||
# Create a collection:
|
||||
self.learning_package = authoring_api.get_learning_package_by_key(self.library.key)
|
||||
self.learning_package = content_api.get_learning_package_by_key(self.library.key)
|
||||
with freeze_time(self.created_date):
|
||||
self.collection = authoring_api.create_collection(
|
||||
self.collection = content_api.create_collection(
|
||||
learning_package_id=self.learning_package.id,
|
||||
key="MYCOL",
|
||||
title="my_collection",
|
||||
@@ -926,7 +926,7 @@ class TestSearchApi(ModuleStoreTestCase):
|
||||
mock_meilisearch.return_value.index.reset_mock()
|
||||
|
||||
# Soft-delete the collection
|
||||
authoring_api.delete_collection(
|
||||
content_api.delete_collection(
|
||||
self.collection.learning_package_id,
|
||||
self.collection.key,
|
||||
)
|
||||
@@ -961,7 +961,7 @@ class TestSearchApi(ModuleStoreTestCase):
|
||||
# Restore the collection
|
||||
restored_date = datetime(2023, 8, 9, 10, 11, 12, tzinfo=timezone.utc)
|
||||
with freeze_time(restored_date):
|
||||
authoring_api.restore_collection(
|
||||
content_api.restore_collection(
|
||||
self.collection.learning_package_id,
|
||||
self.collection.key,
|
||||
)
|
||||
@@ -983,7 +983,7 @@ class TestSearchApi(ModuleStoreTestCase):
|
||||
mock_meilisearch.return_value.index.reset_mock()
|
||||
|
||||
# Hard-delete the collection
|
||||
authoring_api.delete_collection(
|
||||
content_api.delete_collection(
|
||||
self.collection.learning_package_id,
|
||||
self.collection.key,
|
||||
hard_delete=True,
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime, timezone
|
||||
|
||||
from freezegun import freeze_time
|
||||
from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from organizations.models import Organization
|
||||
|
||||
from openedx.core.djangoapps.content_libraries import api as library_api
|
||||
@@ -660,7 +660,7 @@ class StudioDocumentsTest(SharedModuleStoreTestCase):
|
||||
self.container.container_key,
|
||||
[block_2.usage_key],
|
||||
user_id=None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
doc = searchable_doc_for_container(self.container.container_key)
|
||||
|
||||
@@ -36,8 +36,8 @@ from openedx_events.content_authoring.signals import (
|
||||
LIBRARY_COLLECTION_UPDATED,
|
||||
LIBRARY_CONTAINER_UPDATED
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import (
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import (
|
||||
Component, ComponentVersion, LearningPackage, MediaType,
|
||||
Container, Collection
|
||||
)
|
||||
@@ -115,7 +115,7 @@ def get_library_components(
|
||||
lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined]
|
||||
learning_package = lib.learning_package
|
||||
assert learning_package is not None
|
||||
components = authoring_api.get_components(
|
||||
components = content_api.get_components(
|
||||
learning_package.id,
|
||||
draft=True,
|
||||
namespace='xblock.v1',
|
||||
@@ -133,7 +133,7 @@ def get_library_containers(library_key: LibraryLocatorV2) -> QuerySet[Container]
|
||||
lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined]
|
||||
learning_package = lib.learning_package
|
||||
assert learning_package is not None
|
||||
containers: QuerySet[Container] = authoring_api.get_containers(
|
||||
containers: QuerySet[Container] = content_api.get_containers(
|
||||
learning_package.id
|
||||
)
|
||||
|
||||
@@ -147,7 +147,7 @@ def get_library_collections(library_key: LibraryLocatorV2) -> QuerySet[Collectio
|
||||
lib = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined]
|
||||
learning_package = lib.learning_package
|
||||
assert learning_package is not None
|
||||
collections = authoring_api.get_collections(
|
||||
collections = content_api.get_collections(
|
||||
learning_package.id
|
||||
)
|
||||
return collections
|
||||
@@ -177,7 +177,7 @@ def get_library_block(usage_key: LibraryUsageLocatorV2, include_collections=Fals
|
||||
raise ContentLibraryBlockNotFound(usage_key)
|
||||
|
||||
if include_collections:
|
||||
associated_collections = authoring_api.get_entity_collections(
|
||||
associated_collections = content_api.get_entity_collections(
|
||||
component.learning_package_id,
|
||||
component.key,
|
||||
).values('key', 'title')
|
||||
@@ -238,13 +238,13 @@ def set_library_block_olx(usage_key: LibraryUsageLocatorV2, new_olx_str: str) ->
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
|
||||
with transaction.atomic():
|
||||
new_content = authoring_api.get_or_create_text_content(
|
||||
new_content = content_api.get_or_create_text_content(
|
||||
component.learning_package_id,
|
||||
get_or_create_olx_media_type(usage_key.block_type).id,
|
||||
text=new_olx_str,
|
||||
created=now,
|
||||
)
|
||||
new_component_version = authoring_api.create_next_component_version(
|
||||
new_component_version = content_api.create_next_component_version(
|
||||
component.pk,
|
||||
title=new_title,
|
||||
content_to_replace={
|
||||
@@ -295,7 +295,7 @@ def validate_can_add_block_to_library(
|
||||
|
||||
# If adding a component would take us over our max, return an error.
|
||||
assert content_library.learning_package_id is not None
|
||||
component_count = authoring_api.get_all_drafts(content_library.learning_package_id).count()
|
||||
component_count = content_api.get_all_drafts(content_library.learning_package_id).count()
|
||||
if component_count + 1 > settings.MAX_BLOCKS_PER_CONTENT_LIBRARY:
|
||||
raise BlockLimitReachedError(
|
||||
_("Library cannot have more than {} Components.").format(
|
||||
@@ -419,10 +419,10 @@ def _import_staged_block(
|
||||
with transaction.atomic(savepoint=False):
|
||||
# First create the Component, but do not initialize it to anything (i.e.
|
||||
# no ComponentVersion).
|
||||
component_type = authoring_api.get_or_create_component_type(
|
||||
component_type = content_api.get_or_create_component_type(
|
||||
"xblock.v1", usage_key.block_type
|
||||
)
|
||||
component = authoring_api.create_component(
|
||||
component = content_api.create_component(
|
||||
learning_package.id,
|
||||
component_type=component_type,
|
||||
local_key=usage_key.block_id,
|
||||
@@ -480,14 +480,14 @@ def _import_staged_block(
|
||||
if not media_type_str:
|
||||
media_type_str = "application/octet-stream"
|
||||
|
||||
media_type = authoring_api.get_or_create_media_type(media_type_str)
|
||||
content = authoring_api.get_or_create_file_content(
|
||||
media_type = content_api.get_or_create_media_type(media_type_str)
|
||||
content = content_api.get_or_create_file_content(
|
||||
learning_package.id,
|
||||
media_type.id,
|
||||
data=file_data,
|
||||
created=now,
|
||||
)
|
||||
authoring_api.create_component_version_content(
|
||||
content_api.create_component_version_content(
|
||||
component_version.pk,
|
||||
content.id,
|
||||
key=filename,
|
||||
@@ -690,7 +690,7 @@ def get_or_create_olx_media_type(block_type: str) -> MediaType:
|
||||
Learning Core stores all Content with a Media Type (a.k.a. MIME type). For
|
||||
OLX, we use the "application/vnd.*" convention, per RFC 6838.
|
||||
"""
|
||||
return authoring_api.get_or_create_media_type(
|
||||
return content_api.get_or_create_media_type(
|
||||
f"application/vnd.openedx.xblock.v1.{block_type}+xml"
|
||||
)
|
||||
|
||||
@@ -704,10 +704,10 @@ def delete_library_block(
|
||||
"""
|
||||
component = get_component_from_usage_key(usage_key)
|
||||
library_key = usage_key.context_key
|
||||
affected_collections = authoring_api.get_entity_collections(component.learning_package_id, component.key)
|
||||
affected_collections = content_api.get_entity_collections(component.learning_package_id, component.key)
|
||||
affected_containers = get_containers_contains_item(usage_key)
|
||||
|
||||
authoring_api.soft_delete_draft(component.pk, deleted_by=user_id)
|
||||
content_api.soft_delete_draft(component.pk, deleted_by=user_id)
|
||||
|
||||
# .. event_implemented_name: LIBRARY_BLOCK_DELETED
|
||||
# .. event_type: org.openedx.content_authoring.library_block.deleted.v1
|
||||
@@ -756,10 +756,10 @@ def restore_library_block(usage_key: LibraryUsageLocatorV2, user_id: int | None
|
||||
"""
|
||||
component = get_component_from_usage_key(usage_key)
|
||||
library_key = usage_key.context_key
|
||||
affected_collections = authoring_api.get_entity_collections(component.learning_package_id, component.key)
|
||||
affected_collections = content_api.get_entity_collections(component.learning_package_id, component.key)
|
||||
|
||||
# Set draft version back to the latest available component version id.
|
||||
authoring_api.set_draft_version(
|
||||
content_api.set_draft_version(
|
||||
component.pk,
|
||||
component.versioning.latest.pk,
|
||||
set_by=user_id,
|
||||
@@ -895,7 +895,7 @@ def add_library_block_static_asset_file(
|
||||
component = get_component_from_usage_key(usage_key)
|
||||
|
||||
with transaction.atomic():
|
||||
component_version = authoring_api.create_next_component_version(
|
||||
component_version = content_api.create_next_component_version(
|
||||
component.pk,
|
||||
content_to_replace={file_path: file_content},
|
||||
created=datetime.now(tz=timezone.utc),
|
||||
@@ -943,7 +943,7 @@ def delete_library_block_static_asset_file(usage_key, file_path, user=None):
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
|
||||
with transaction.atomic():
|
||||
component_version = authoring_api.create_next_component_version(
|
||||
component_version = content_api.create_next_component_version(
|
||||
component.pk,
|
||||
content_to_replace={file_path: None},
|
||||
created=now,
|
||||
@@ -971,9 +971,9 @@ def publish_component_changes(usage_key: LibraryUsageLocatorV2, user_id: int):
|
||||
learning_package = content_library.learning_package
|
||||
assert learning_package
|
||||
# The core publishing API is based on draft objects, so find the draft that corresponds to this component:
|
||||
drafts_to_publish = authoring_api.get_all_drafts(learning_package.id).filter(entity__key=component.key)
|
||||
drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__key=component.key)
|
||||
# Publish the component and update anything that needs to be updated (e.g. search index):
|
||||
publish_log = authoring_api.publish_from_drafts(
|
||||
publish_log = content_api.publish_from_drafts(
|
||||
learning_package.id, draft_qset=drafts_to_publish, published_by=user_id,
|
||||
)
|
||||
# Since this is a single component, it should be safe to process synchronously and in-process:
|
||||
@@ -1026,10 +1026,10 @@ def _create_component_for_block(
|
||||
assert learning_package is not None # mostly for type checker
|
||||
|
||||
with transaction.atomic():
|
||||
component_type = authoring_api.get_or_create_component_type(
|
||||
component_type = content_api.get_or_create_component_type(
|
||||
"xblock.v1", usage_key.block_type
|
||||
)
|
||||
component, component_version = authoring_api.create_component_and_version(
|
||||
component, component_version = content_api.create_component_and_version(
|
||||
learning_package.id,
|
||||
component_type=component_type,
|
||||
local_key=usage_key.block_id,
|
||||
@@ -1038,13 +1038,13 @@ def _create_component_for_block(
|
||||
created_by=user_id,
|
||||
can_stand_alone=can_stand_alone,
|
||||
)
|
||||
content = authoring_api.get_or_create_text_content(
|
||||
content = content_api.get_or_create_text_content(
|
||||
learning_package.id,
|
||||
get_or_create_olx_media_type(usage_key.block_type).id,
|
||||
text=xml_text,
|
||||
created=now,
|
||||
)
|
||||
authoring_api.create_component_version_content(
|
||||
content_api.create_component_version_content(
|
||||
component_version.pk,
|
||||
content.id,
|
||||
key="block.xml",
|
||||
|
||||
@@ -8,8 +8,8 @@ from opaque_keys.edx.keys import BlockTypeKey, UsageKeyV2
|
||||
from opaque_keys.edx.locator import LibraryCollectionLocator, LibraryContainerLocator, LibraryLocatorV2
|
||||
from openedx_events.content_authoring.data import LibraryCollectionData
|
||||
from openedx_events.content_authoring.signals import LIBRARY_COLLECTION_UPDATED
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Collection, Component, PublishableEntity
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Collection, Component, PublishableEntity
|
||||
|
||||
from ..models import ContentLibrary
|
||||
from .exceptions import (
|
||||
@@ -52,7 +52,7 @@ def create_library_collection(
|
||||
assert content_library.library_key == library_key
|
||||
|
||||
try:
|
||||
collection = authoring_api.create_collection(
|
||||
collection = content_api.create_collection(
|
||||
learning_package_id=content_library.learning_package_id,
|
||||
key=collection_key,
|
||||
title=title,
|
||||
@@ -84,7 +84,7 @@ def update_library_collection(
|
||||
assert content_library.library_key == library_key
|
||||
|
||||
try:
|
||||
collection = authoring_api.update_collection(
|
||||
collection = content_api.update_collection(
|
||||
learning_package_id=content_library.learning_package_id,
|
||||
key=collection_key,
|
||||
title=title,
|
||||
@@ -132,7 +132,7 @@ def update_library_collection_items(
|
||||
for opaque_key in opaque_keys:
|
||||
if isinstance(opaque_key, LibraryContainerLocator):
|
||||
try:
|
||||
container = authoring_api.get_container_by_key(
|
||||
container = content_api.get_container_by_key(
|
||||
content_library.learning_package_id,
|
||||
key=opaque_key.container_id,
|
||||
)
|
||||
@@ -144,7 +144,7 @@ def update_library_collection_items(
|
||||
# Parse the block_family from the key to use as namespace.
|
||||
block_type = BlockTypeKey.from_string(str(opaque_key))
|
||||
try:
|
||||
component = authoring_api.get_component_by_key(
|
||||
component = content_api.get_component_by_key(
|
||||
content_library.learning_package_id,
|
||||
namespace=block_type.block_family,
|
||||
type_name=opaque_key.block_type,
|
||||
@@ -163,13 +163,13 @@ def update_library_collection_items(
|
||||
)
|
||||
|
||||
if remove:
|
||||
collection = authoring_api.remove_from_collection(
|
||||
collection = content_api.remove_from_collection(
|
||||
content_library.learning_package_id,
|
||||
collection_key,
|
||||
entities_qset,
|
||||
)
|
||||
else:
|
||||
collection = authoring_api.add_to_collection(
|
||||
collection = content_api.add_to_collection(
|
||||
content_library.learning_package_id,
|
||||
collection_key,
|
||||
entities_qset,
|
||||
@@ -207,17 +207,17 @@ def set_library_item_collections(
|
||||
assert content_library.learning_package_id
|
||||
assert content_library.library_key == library_key
|
||||
|
||||
publishable_entity = authoring_api.get_publishable_entity_by_key(
|
||||
publishable_entity = content_api.get_publishable_entity_by_key(
|
||||
content_library.learning_package_id,
|
||||
key=entity_key,
|
||||
)
|
||||
|
||||
# Note: Component.key matches its PublishableEntity.key
|
||||
collection_qs = authoring_api.get_collections(content_library.learning_package_id).filter(
|
||||
collection_qs = content_api.get_collections(content_library.learning_package_id).filter(
|
||||
key__in=collection_keys
|
||||
)
|
||||
|
||||
affected_collections = authoring_api.set_collections(
|
||||
affected_collections = content_api.set_collections(
|
||||
publishable_entity,
|
||||
collection_qs,
|
||||
created_by=created_by,
|
||||
@@ -263,7 +263,7 @@ def get_library_collection_from_locator(
|
||||
content_library = ContentLibrary.objects.get_by_key(library_key) # type: ignore[attr-defined]
|
||||
assert content_library.learning_package_id is not None # shouldn't happen but it's technically possible.
|
||||
try:
|
||||
return authoring_api.get_collection(
|
||||
return content_api.get_collection(
|
||||
content_library.learning_package_id,
|
||||
collection_key,
|
||||
)
|
||||
|
||||
@@ -8,8 +8,8 @@ from enum import Enum
|
||||
from django.db.models import QuerySet
|
||||
|
||||
from opaque_keys.edx.locator import LibraryContainerLocator, LibraryLocatorV2, LibraryUsageLocatorV2
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import (
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import (
|
||||
Component,
|
||||
Container,
|
||||
ContainerVersion,
|
||||
@@ -149,7 +149,7 @@ class ContainerMetadata(PublishableItem):
|
||||
published_by=published_by,
|
||||
last_draft_created=last_draft_created,
|
||||
last_draft_created_by=last_draft_created_by,
|
||||
has_unpublished_changes=authoring_api.contains_unpublished_changes(container.pk),
|
||||
has_unpublished_changes=content_api.contains_unpublished_changes(container.pk),
|
||||
tags_count=tags.get(str(container_key), 0),
|
||||
collections=associated_collections or [],
|
||||
)
|
||||
@@ -295,7 +295,7 @@ def _get_containers_with_entities(
|
||||
"""
|
||||
qs = Container.objects.none()
|
||||
for member in members:
|
||||
qs = qs.union(authoring_api.get_containers_with_entity(
|
||||
qs = qs.union(content_api.get_containers_with_entity(
|
||||
member.entity.pk,
|
||||
ignore_pinned=ignore_pinned,
|
||||
))
|
||||
@@ -320,7 +320,7 @@ def _get_containers_children(
|
||||
for member in members:
|
||||
container = member.container
|
||||
assert container
|
||||
for entry in authoring_api.get_entities_in_container(
|
||||
for entry in content_api.get_entities_in_container(
|
||||
container,
|
||||
published=published,
|
||||
):
|
||||
@@ -372,7 +372,7 @@ class ContainerHierarchyMember:
|
||||
container=entity,
|
||||
),
|
||||
display_name=entity.versioning.draft.title,
|
||||
has_unpublished_changes=authoring_api.contains_unpublished_changes(entity.pk),
|
||||
has_unpublished_changes=content_api.contains_unpublished_changes(entity.pk),
|
||||
container=entity,
|
||||
component=None,
|
||||
)
|
||||
@@ -425,7 +425,7 @@ def get_container_from_key(container_key: LibraryContainerLocator, include_delet
|
||||
content_library = ContentLibrary.objects.get_by_key(container_key.lib_key)
|
||||
learning_package = content_library.learning_package
|
||||
assert learning_package is not None
|
||||
container = authoring_api.get_container_by_key(
|
||||
container = content_api.get_container_by_key(
|
||||
learning_package.id,
|
||||
key=container_key.container_id,
|
||||
)
|
||||
|
||||
@@ -22,8 +22,8 @@ from openedx_events.content_authoring.signals import (
|
||||
LIBRARY_CONTAINER_DELETED,
|
||||
LIBRARY_CONTAINER_UPDATED,
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Container, ContainerVersion, Component
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Container, ContainerVersion, Component
|
||||
from openedx.core.djangoapps.content_libraries.api.collections import library_collection_locator
|
||||
|
||||
from openedx.core.djangoapps.xblock.api import get_component_from_usage_key
|
||||
@@ -76,7 +76,7 @@ def get_container(
|
||||
"""
|
||||
container = get_container_from_key(container_key)
|
||||
if include_collections:
|
||||
associated_collections = authoring_api.get_entity_collections(
|
||||
associated_collections = content_api.get_entity_collections(
|
||||
container.publishable_entity.learning_package_id,
|
||||
container_key.container_id,
|
||||
).values('key', 'title')
|
||||
@@ -126,7 +126,7 @@ def create_container(
|
||||
# Then try creating the actual container:
|
||||
match container_type:
|
||||
case ContainerType.Unit:
|
||||
container, _initial_version = authoring_api.create_unit_and_version(
|
||||
container, _initial_version = content_api.create_unit_and_version(
|
||||
content_library.learning_package_id,
|
||||
key=slug,
|
||||
title=title,
|
||||
@@ -134,7 +134,7 @@ def create_container(
|
||||
created_by=user_id,
|
||||
)
|
||||
case ContainerType.Subsection:
|
||||
container, _initial_version = authoring_api.create_subsection_and_version(
|
||||
container, _initial_version = content_api.create_subsection_and_version(
|
||||
content_library.learning_package_id,
|
||||
key=slug,
|
||||
title=title,
|
||||
@@ -142,7 +142,7 @@ def create_container(
|
||||
created_by=user_id,
|
||||
)
|
||||
case ContainerType.Section:
|
||||
container, _initial_version = authoring_api.create_section_and_version(
|
||||
container, _initial_version = content_api.create_section_and_version(
|
||||
content_library.learning_package_id,
|
||||
key=slug,
|
||||
title=title,
|
||||
@@ -188,7 +188,7 @@ def update_container(
|
||||
|
||||
match container_type:
|
||||
case ContainerType.Unit:
|
||||
version = authoring_api.create_next_unit_version(
|
||||
version = content_api.create_next_unit_version(
|
||||
container.unit,
|
||||
title=display_name,
|
||||
created=created,
|
||||
@@ -198,7 +198,7 @@ def update_container(
|
||||
# Components have usage_key instead of container_key
|
||||
child_key_name = 'usage_key'
|
||||
case ContainerType.Subsection:
|
||||
version = authoring_api.create_next_subsection_version(
|
||||
version = content_api.create_next_subsection_version(
|
||||
container.subsection,
|
||||
title=display_name,
|
||||
created=created,
|
||||
@@ -206,7 +206,7 @@ def update_container(
|
||||
)
|
||||
affected_containers = get_containers_contains_item(container_key)
|
||||
case ContainerType.Section:
|
||||
version = authoring_api.create_next_section_version(
|
||||
version = content_api.create_next_section_version(
|
||||
container.section,
|
||||
title=display_name,
|
||||
created=created,
|
||||
@@ -265,7 +265,7 @@ def delete_container(
|
||||
container = get_container_from_key(container_key)
|
||||
|
||||
# Fetch related collections and containers before soft-delete
|
||||
affected_collections = authoring_api.get_entity_collections(
|
||||
affected_collections = content_api.get_entity_collections(
|
||||
container.publishable_entity.learning_package_id,
|
||||
container.key,
|
||||
)
|
||||
@@ -275,7 +275,7 @@ def delete_container(
|
||||
container_key,
|
||||
published=False,
|
||||
)
|
||||
authoring_api.soft_delete_draft(container.pk)
|
||||
content_api.soft_delete_draft(container.pk)
|
||||
|
||||
# .. event_implemented_name: LIBRARY_CONTAINER_DELETED
|
||||
# .. event_type: org.openedx.content_authoring.content_library.container.deleted.v1
|
||||
@@ -337,12 +337,12 @@ def restore_container(container_key: LibraryContainerLocator) -> None:
|
||||
library_key = container_key.lib_key
|
||||
container = get_container_from_key(container_key, include_deleted=True)
|
||||
|
||||
affected_collections = authoring_api.get_entity_collections(
|
||||
affected_collections = content_api.get_entity_collections(
|
||||
container.publishable_entity.learning_package_id,
|
||||
container.key,
|
||||
)
|
||||
|
||||
authoring_api.set_draft_version(container.pk, container.versioning.latest.pk)
|
||||
content_api.set_draft_version(container.pk, container.versioning.latest.pk)
|
||||
# Fetch related containers after restore
|
||||
affected_containers = get_containers_contains_item(container_key)
|
||||
# Get children containers or components to update their index data
|
||||
@@ -430,25 +430,25 @@ def get_container_children(
|
||||
|
||||
match container_type:
|
||||
case ContainerType.Unit:
|
||||
child_components = authoring_api.get_components_in_unit(container.unit, published=published)
|
||||
child_components = content_api.get_components_in_unit(container.unit, published=published)
|
||||
return [LibraryXBlockMetadata.from_component(
|
||||
container_key.lib_key,
|
||||
entry.component
|
||||
) for entry in child_components]
|
||||
case ContainerType.Subsection:
|
||||
child_units = authoring_api.get_units_in_subsection(container.subsection, published=published)
|
||||
child_units = content_api.get_units_in_subsection(container.subsection, published=published)
|
||||
return [ContainerMetadata.from_container(
|
||||
container_key.lib_key,
|
||||
entry.unit
|
||||
) for entry in child_units]
|
||||
case ContainerType.Section:
|
||||
child_subsections = authoring_api.get_subsections_in_section(container.section, published=published)
|
||||
child_subsections = content_api.get_subsections_in_section(container.section, published=published)
|
||||
return [ContainerMetadata.from_container(
|
||||
container_key.lib_key,
|
||||
entry.subsection,
|
||||
) for entry in child_subsections]
|
||||
case _:
|
||||
child_entities = authoring_api.get_entities_in_container(container, published=published)
|
||||
child_entities = content_api.get_entities_in_container(container, published=published)
|
||||
return [ContainerMetadata.from_container(
|
||||
container_key.lib_key,
|
||||
entry.entity
|
||||
@@ -463,14 +463,14 @@ def get_container_children_count(
|
||||
[ 🛑 UNSTABLE ] Get the count of entities contained in the given container (e.g. the components/xblocks in a unit)
|
||||
"""
|
||||
container = get_container_from_key(container_key)
|
||||
return authoring_api.get_container_children_count(container, published=published)
|
||||
return content_api.get_container_children_count(container, published=published)
|
||||
|
||||
|
||||
def update_container_children(
|
||||
container_key: LibraryContainerLocator,
|
||||
children_ids: list[LibraryUsageLocatorV2] | list[LibraryContainerLocator],
|
||||
user_id: int | None,
|
||||
entities_action: authoring_api.ChildrenEntitiesAction = authoring_api.ChildrenEntitiesAction.REPLACE,
|
||||
entities_action: content_api.ChildrenEntitiesAction = content_api.ChildrenEntitiesAction.REPLACE,
|
||||
):
|
||||
"""
|
||||
[ 🛑 UNSTABLE ] Adds children components or containers to given container.
|
||||
@@ -483,7 +483,7 @@ def update_container_children(
|
||||
match container_type:
|
||||
case ContainerType.Unit:
|
||||
components = [get_component_from_usage_key(key) for key in children_ids] # type: ignore[arg-type]
|
||||
new_version = authoring_api.create_next_unit_version(
|
||||
new_version = content_api.create_next_unit_version(
|
||||
container.unit,
|
||||
components=components, # type: ignore[arg-type]
|
||||
created=created,
|
||||
@@ -502,7 +502,7 @@ def update_container_children(
|
||||
)
|
||||
case ContainerType.Subsection:
|
||||
units = [get_container_from_key(key).unit for key in children_ids] # type: ignore[arg-type]
|
||||
new_version = authoring_api.create_next_subsection_version(
|
||||
new_version = content_api.create_next_subsection_version(
|
||||
container.subsection,
|
||||
units=units, # type: ignore[arg-type]
|
||||
created=created,
|
||||
@@ -521,7 +521,7 @@ def update_container_children(
|
||||
)
|
||||
case ContainerType.Section:
|
||||
subsections = [get_container_from_key(key).subsection for key in children_ids] # type: ignore[arg-type]
|
||||
new_version = authoring_api.create_next_section_version(
|
||||
new_version = content_api.create_next_section_version(
|
||||
container.section,
|
||||
subsections=subsections, # type: ignore[arg-type]
|
||||
created=created,
|
||||
@@ -566,7 +566,7 @@ def get_containers_contains_item(
|
||||
elif isinstance(key, LibraryContainerLocator):
|
||||
item = get_container_from_key(key)
|
||||
|
||||
containers = authoring_api.get_containers_with_entity(
|
||||
containers = content_api.get_containers_with_entity(
|
||||
item.publishable_entity.pk,
|
||||
)
|
||||
return [
|
||||
@@ -590,9 +590,9 @@ def publish_container_changes(
|
||||
learning_package = content_library.learning_package
|
||||
assert learning_package
|
||||
# The core publishing API is based on draft objects, so find the draft that corresponds to this container:
|
||||
drafts_to_publish = authoring_api.get_all_drafts(learning_package.id).filter(entity__pk=container.pk)
|
||||
drafts_to_publish = content_api.get_all_drafts(learning_package.id).filter(entity__pk=container.pk)
|
||||
# Publish the container, which will also auto-publish any unpublished child components:
|
||||
publish_log = authoring_api.publish_from_drafts(
|
||||
publish_log = content_api.publish_from_drafts(
|
||||
learning_package.id,
|
||||
draft_qset=drafts_to_publish,
|
||||
published_by=user_id,
|
||||
|
||||
@@ -3,7 +3,7 @@ Exceptions that can be thrown by the Content Libraries API.
|
||||
"""
|
||||
from django.db import IntegrityError
|
||||
|
||||
from openedx_learning.api.authoring_models import Collection, Container
|
||||
from openedx_content.models_api import Collection, Container
|
||||
from xblock.exceptions import XBlockNotFoundError
|
||||
|
||||
from ..models import ContentLibrary
|
||||
|
||||
@@ -63,8 +63,8 @@ from openedx_events.content_authoring.signals import (
|
||||
CONTENT_LIBRARY_DELETED,
|
||||
CONTENT_LIBRARY_UPDATED,
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Component, LearningPackage
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Component, LearningPackage
|
||||
from organizations.models import Organization
|
||||
from user_tasks.models import UserTaskArtifact, UserTaskStatus
|
||||
from xblock.core import XBlock
|
||||
@@ -364,9 +364,9 @@ def get_library(library_key: LibraryLocatorV2) -> ContentLibraryMetadata:
|
||||
ref = ContentLibrary.objects.get_by_key(library_key)
|
||||
learning_package = ref.learning_package
|
||||
assert learning_package is not None # Shouldn't happen - this is just for the type checker
|
||||
num_blocks = authoring_api.get_all_drafts(learning_package.id).count()
|
||||
last_publish_log = authoring_api.get_last_publish(learning_package.id)
|
||||
last_draft_log = authoring_api.get_entities_with_unpublished_changes(learning_package.id) \
|
||||
num_blocks = content_api.get_all_drafts(learning_package.id).count()
|
||||
last_publish_log = content_api.get_last_publish(learning_package.id)
|
||||
last_draft_log = content_api.get_entities_with_unpublished_changes(learning_package.id) \
|
||||
.order_by('-created').first()
|
||||
last_draft_created = last_draft_log.created if last_draft_log else None
|
||||
last_draft_created_by = last_draft_log.created_by.username if last_draft_log and last_draft_log.created_by else ""
|
||||
@@ -377,8 +377,9 @@ def get_library(library_key: LibraryLocatorV2) -> ContentLibraryMetadata:
|
||||
# with how Blockstore staged changes, but Learning Core works differently,
|
||||
# and has_unpublished_changes should be sufficient.
|
||||
# Ref: https://github.com/openedx/edx-platform/issues/34283
|
||||
has_unpublished_deletes = authoring_api.get_entities_with_unpublished_deletes(learning_package.id) \
|
||||
.exists()
|
||||
has_unpublished_deletes = (
|
||||
content_api.get_entities_with_unpublished_deletes(learning_package.id).exists()
|
||||
)
|
||||
|
||||
published_by = ""
|
||||
if last_publish_log and last_publish_log.published_by:
|
||||
@@ -450,7 +451,7 @@ def create_library(
|
||||
if learning_package:
|
||||
# A temporary LearningPackage was passed in, so update its key to match the library,
|
||||
# and also update its title/description in case they differ.
|
||||
authoring_api.update_learning_package(
|
||||
content_api.update_learning_package(
|
||||
learning_package.id,
|
||||
key=str(ref.library_key),
|
||||
title=title,
|
||||
@@ -458,7 +459,7 @@ def create_library(
|
||||
)
|
||||
else:
|
||||
# We have to generate a new LearningPackage for this library.
|
||||
learning_package = authoring_api.create_learning_package(
|
||||
learning_package = content_api.create_learning_package(
|
||||
key=str(ref.library_key),
|
||||
title=title,
|
||||
description=description,
|
||||
@@ -485,7 +486,7 @@ def create_library(
|
||||
allow_public_learning=ref.allow_public_learning,
|
||||
allow_public_read=ref.allow_public_read,
|
||||
license=library_license,
|
||||
learning_package_id=ref.learning_package.pk,
|
||||
learning_package_id=ref.learning_package.pk, # type: ignore[union-attr]
|
||||
)
|
||||
|
||||
|
||||
@@ -625,7 +626,7 @@ def update_library(
|
||||
content_lib.save()
|
||||
|
||||
if learning_pkg_changed:
|
||||
authoring_api.update_learning_package(
|
||||
content_api.update_learning_package(
|
||||
learning_package_id,
|
||||
title=title,
|
||||
description=description,
|
||||
@@ -717,7 +718,7 @@ def publish_changes(library_key: LibraryLocatorV2, user_id: int | None = None):
|
||||
"""
|
||||
learning_package = ContentLibrary.objects.get_by_key(library_key).learning_package
|
||||
assert learning_package is not None # shouldn't happen but it's technically possible.
|
||||
publish_log = authoring_api.publish_all_drafts(learning_package.id, published_by=user_id)
|
||||
publish_log = content_api.publish_all_drafts(learning_package.id, published_by=user_id)
|
||||
|
||||
# Update the search index (and anything else) for the affected blocks
|
||||
# This is mostly synchronous but may complete some work asynchronously if there are a lot of changes.
|
||||
@@ -735,8 +736,8 @@ def revert_changes(library_key: LibraryLocatorV2, user_id: int | None = None) ->
|
||||
"""
|
||||
learning_package = ContentLibrary.objects.get_by_key(library_key).learning_package
|
||||
assert learning_package is not None # shouldn't happen but it's technically possible.
|
||||
with authoring_api.bulk_draft_changes_for(learning_package.id) as draft_change_log:
|
||||
authoring_api.reset_drafts_to_published(learning_package.id, reset_by=user_id)
|
||||
with content_api.bulk_draft_changes_for(learning_package.id) as draft_change_log:
|
||||
content_api.reset_drafts_to_published(learning_package.id, reset_by=user_id)
|
||||
|
||||
# Call the event handlers as needed.
|
||||
tasks.wait_for_post_revert_events(draft_change_log, library_key)
|
||||
|
||||
@@ -10,7 +10,7 @@ from openedx_events.content_authoring.data import LibraryBlockData, LibraryConta
|
||||
from openedx_events.content_authoring.signals import LIBRARY_BLOCK_UPDATED, LIBRARY_CONTAINER_UPDATED
|
||||
from opaque_keys.edx.keys import UsageKeyV2
|
||||
from opaque_keys.edx.locator import LibraryUsageLocatorV2, LibraryLocatorV2
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
|
||||
from openedx.core.djangoapps.content_libraries import api, permissions
|
||||
from openedx.core.djangoapps.content_libraries.models import ContentLibrary
|
||||
@@ -96,7 +96,7 @@ class LibraryContextImpl(LearningContext):
|
||||
if learning_package is None:
|
||||
return False
|
||||
|
||||
return authoring_api.component_exists_by_key(
|
||||
return content_api.component_exists_by_key(
|
||||
learning_package.id,
|
||||
namespace='xblock.v1',
|
||||
type_name=usage_key.block_type,
|
||||
|
||||
@@ -57,7 +57,7 @@ from opaque_keys.edx.django.models import UsageKeyField
|
||||
from openedx.core.djangoapps.content_libraries.constants import (
|
||||
LICENSE_OPTIONS, ALL_RIGHTS_RESERVED,
|
||||
)
|
||||
from openedx_learning.api.authoring_models import LearningPackage
|
||||
from openedx_content.models_api import LearningPackage
|
||||
from organizations.models import Organization # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from .apps import ContentLibrariesConfig
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.utils.decorators import method_decorator
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2
|
||||
from openedx_authz.constants import permissions as authz_permissions
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from rest_framework import status
|
||||
from rest_framework.exceptions import NotFound, ValidationError
|
||||
from rest_framework.generics import GenericAPIView
|
||||
@@ -392,7 +392,7 @@ def get_component_version_asset(request, component_version_uuid, asset_path):
|
||||
eventually).
|
||||
"""
|
||||
try:
|
||||
component_version = authoring_api.get_component_version_by_uuid(
|
||||
component_version = content_api.get_component_version_by_uuid(
|
||||
component_version_uuid
|
||||
)
|
||||
except ObjectDoesNotExist as exc:
|
||||
@@ -411,7 +411,7 @@ def get_component_version_asset(request, component_version_uuid, asset_path):
|
||||
# this response in conjunction with a media reverse proxy (Caddy or Nginx),
|
||||
# but in the short term we're just going to remove the redirect and stream
|
||||
# the content directly.
|
||||
redirect_response = authoring_api.get_redirect_response_for_component_asset(
|
||||
redirect_response = content_api.get_redirect_response_for_component_asset(
|
||||
component_version_uuid,
|
||||
asset_path,
|
||||
public=False,
|
||||
|
||||
@@ -14,8 +14,8 @@ from rest_framework.status import HTTP_204_NO_CONTENT
|
||||
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_authz.constants import permissions as authz_permissions
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Collection
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Collection
|
||||
|
||||
from .. import api, permissions
|
||||
from ..models import ContentLibrary
|
||||
@@ -72,7 +72,7 @@ class LibraryCollectionsView(ModelViewSet):
|
||||
"""
|
||||
content_library = self.get_content_library()
|
||||
assert content_library.learning_package_id
|
||||
return authoring_api.get_collections(content_library.learning_package_id)
|
||||
return content_api.get_collections(content_library.learning_package_id)
|
||||
|
||||
def get_object(self) -> Collection:
|
||||
"""
|
||||
@@ -183,7 +183,7 @@ class LibraryCollectionsView(ModelViewSet):
|
||||
)
|
||||
collection = super().get_object()
|
||||
assert collection.learning_package_id
|
||||
authoring_api.delete_collection(
|
||||
content_api.delete_collection(
|
||||
collection.learning_package_id,
|
||||
collection.key,
|
||||
hard_delete=False,
|
||||
@@ -204,7 +204,7 @@ class LibraryCollectionsView(ModelViewSet):
|
||||
)
|
||||
assert content_library.learning_package_id
|
||||
collection_key = kwargs["key"]
|
||||
authoring_api.restore_collection(
|
||||
content_api.restore_collection(
|
||||
content_library.learning_package_id,
|
||||
collection_key,
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ from drf_yasg import openapi
|
||||
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2, LibraryContainerLocator
|
||||
from openedx_authz.constants import permissions as authz_permissions
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
from rest_framework.generics import GenericAPIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.status import HTTP_204_NO_CONTENT, HTTP_200_OK
|
||||
@@ -200,7 +200,7 @@ class LibraryContainerChildrenView(GenericAPIView):
|
||||
self,
|
||||
request,
|
||||
container_key: LibraryContainerLocator,
|
||||
action: authoring_api.ChildrenEntitiesAction,
|
||||
action: content_api.ChildrenEntitiesAction,
|
||||
):
|
||||
"""
|
||||
Helper function to update children in container.
|
||||
@@ -237,7 +237,7 @@ class LibraryContainerChildrenView(GenericAPIView):
|
||||
return self._update_component_children(
|
||||
request,
|
||||
container_key,
|
||||
action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
@convert_exceptions
|
||||
@@ -256,7 +256,7 @@ class LibraryContainerChildrenView(GenericAPIView):
|
||||
return self._update_component_children(
|
||||
request,
|
||||
container_key,
|
||||
action=authoring_api.ChildrenEntitiesAction.REMOVE,
|
||||
action=content_api.ChildrenEntitiesAction.REMOVE,
|
||||
)
|
||||
|
||||
@convert_exceptions
|
||||
@@ -275,7 +275,7 @@ class LibraryContainerChildrenView(GenericAPIView):
|
||||
return self._update_component_children(
|
||||
request,
|
||||
container_key,
|
||||
action=authoring_api.ChildrenEntitiesAction.REPLACE,
|
||||
action=content_api.ChildrenEntitiesAction.REPLACE,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import logging
|
||||
from django.core.validators import validate_unicode_slug
|
||||
from opaque_keys import InvalidKeyError, OpaqueKey
|
||||
from opaque_keys.edx.locator import LibraryContainerLocator, LibraryUsageLocatorV2
|
||||
from openedx_learning.api.authoring_models import Collection, LearningPackage
|
||||
from openedx_content.models_api import Collection, LearningPackage
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from user_tasks.models import UserTaskStatus
|
||||
|
||||
@@ -16,8 +16,8 @@ from openedx_events.content_authoring.signals import (
|
||||
LIBRARY_COLLECTION_DELETED,
|
||||
LIBRARY_COLLECTION_UPDATED
|
||||
)
|
||||
from openedx_learning.api.authoring import get_components, get_containers
|
||||
from openedx_learning.api.authoring_models import Collection, CollectionPublishableEntity, PublishableEntity
|
||||
from openedx_content.api import get_components, get_containers
|
||||
from openedx_content.models_api import Collection, CollectionPublishableEntity, PublishableEntity
|
||||
|
||||
from lms.djangoapps.grades.api import signals as grades_signals
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ from openedx_events.content_authoring.signals import (
|
||||
LIBRARY_CONTAINER_PUBLISHED,
|
||||
LIBRARY_CONTAINER_UPDATED
|
||||
)
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring import create_zip_file as create_lib_zip_file
|
||||
from openedx_learning.api.authoring_models import DraftChangeLog, PublishLog
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.api import create_zip_file as create_lib_zip_file
|
||||
from openedx_content.models_api import DraftChangeLog, PublishLog
|
||||
from path import Path
|
||||
from user_tasks.models import UserTaskArtifact
|
||||
from user_tasks.tasks import UserTask, UserTaskStatus
|
||||
@@ -244,7 +244,7 @@ def send_events_after_revert(draft_change_log_id: int, library_key_str: str) ->
|
||||
)
|
||||
# If any collections contain this entity, their item count may need to be updated, e.g. if this was a
|
||||
# newly created component in the collection and is now deleted, or this was deleted and is now re-added.
|
||||
for parent_collection in authoring_api.get_entity_collections(
|
||||
for parent_collection in content_api.get_entity_collections(
|
||||
record.entity.learning_package_id, record.entity.key,
|
||||
):
|
||||
collection_key = api.library_collection_locator(
|
||||
@@ -640,7 +640,7 @@ class LibraryRestoreTask(UserTask):
|
||||
|
||||
TASK_LOGGER.info('Restoring learning package from temporary file %s', tmp_file.name)
|
||||
|
||||
result = authoring_api.load_learning_package(tmp_file.name, user=user)
|
||||
result = content_api.load_learning_package(tmp_file.name, user=user)
|
||||
|
||||
# If there was an error during the load, fail the task with the error log
|
||||
if result.get("status") == "error":
|
||||
|
||||
@@ -29,7 +29,7 @@ from openedx_events.content_authoring.signals import (
|
||||
LIBRARY_CONTAINER_UPDATED,
|
||||
)
|
||||
from openedx_authz.api.users import get_user_role_assignments_in_scope
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
from .. import api
|
||||
@@ -411,7 +411,7 @@ class ContentLibraryCollectionsTest(ContentLibrariesRestApiTest):
|
||||
LIBRARY_COLLECTION_DELETED.connect(event_receiver)
|
||||
|
||||
assert self.lib1.learning_package_id is not None
|
||||
authoring_api.delete_collection(
|
||||
content_api.delete_collection(
|
||||
self.lib1.learning_package_id,
|
||||
self.col1.key,
|
||||
hard_delete=True,
|
||||
@@ -549,8 +549,8 @@ class ContentLibraryCollectionsTest(ContentLibrariesRestApiTest):
|
||||
)
|
||||
|
||||
assert self.lib2.learning_package_id is not None
|
||||
assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col2.key).entities.all()) == 1
|
||||
assert len(authoring_api.get_collection(self.lib2.learning_package_id, self.col3.key).entities.all()) == 1
|
||||
assert len(content_api.get_collection(self.lib2.learning_package_id, self.col2.key).entities.all()) == 1
|
||||
assert len(content_api.get_collection(self.lib2.learning_package_id, self.col3.key).entities.all()) == 1
|
||||
|
||||
self.assertDictContainsEntries(
|
||||
event_receiver.call_args_list[0].kwargs,
|
||||
@@ -1059,7 +1059,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.unit2.container_key,
|
||||
[LibraryUsageLocatorV2.from_string(html_block_1["id"])],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
event_reciver = mock.Mock()
|
||||
@@ -1068,7 +1068,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.unit2.container_key,
|
||||
[LibraryUsageLocatorV2.from_string(html_block_1["id"])],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.REMOVE,
|
||||
entities_action=content_api.ChildrenEntitiesAction.REMOVE,
|
||||
)
|
||||
|
||||
assert event_reciver.call_count == 1
|
||||
@@ -1091,7 +1091,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.subsection2.container_key,
|
||||
[unit4.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
event_reciver = mock.Mock()
|
||||
@@ -1100,7 +1100,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.subsection2.container_key,
|
||||
[unit4.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.REMOVE,
|
||||
entities_action=content_api.ChildrenEntitiesAction.REMOVE,
|
||||
)
|
||||
|
||||
assert event_reciver.call_count == 1
|
||||
@@ -1129,7 +1129,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.section2.container_key,
|
||||
[subsection3.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
event_reciver = mock.Mock()
|
||||
@@ -1138,7 +1138,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.section2.container_key,
|
||||
[subsection3.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.REMOVE,
|
||||
entities_action=content_api.ChildrenEntitiesAction.REMOVE,
|
||||
)
|
||||
|
||||
assert event_reciver.call_count == 1
|
||||
@@ -1171,7 +1171,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
LibraryUsageLocatorV2.from_string(html_block_2["id"])
|
||||
],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
|
||||
assert event_reciver.call_count == 2
|
||||
@@ -1209,7 +1209,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.subsection2.container_key,
|
||||
[unit4.container_key, unit5.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
assert event_reciver.call_count == 2
|
||||
self.assertDictContainsEntries(
|
||||
@@ -1257,7 +1257,7 @@ class ContentLibraryContainersTest(ContentLibrariesRestApiTest):
|
||||
self.section2.container_key,
|
||||
[subsection3.container_key, subsection4.container_key],
|
||||
None,
|
||||
entities_action=authoring_api.ChildrenEntitiesAction.APPEND,
|
||||
entities_action=content_api.ChildrenEntitiesAction.APPEND,
|
||||
)
|
||||
assert event_reciver.call_count == 2
|
||||
self.assertDictContainsEntries(
|
||||
|
||||
@@ -23,7 +23,7 @@ from opaque_keys.edx.locator import LibraryLocatorV2, LibraryUsageLocatorV2, Lib
|
||||
from organizations.models import Organization
|
||||
from rest_framework.test import APITestCase
|
||||
from rest_framework import status
|
||||
from openedx_learning.api.authoring_models import LearningPackage
|
||||
from openedx_content.models_api import LearningPackage
|
||||
from user_tasks.models import UserTaskStatus, UserTaskArtifact
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
@@ -1179,7 +1179,7 @@ class LibraryRestoreViewTestCase(ContentLibrariesRestApiTest):
|
||||
|
||||
with self.as_user(self.admin_user):
|
||||
with patch(
|
||||
"openedx.core.djangoapps.content_libraries.tasks.authoring_api.load_learning_package",
|
||||
"openedx.core.djangoapps.content_libraries.tasks.content_api.load_learning_package",
|
||||
return_value=error_result
|
||||
):
|
||||
response = self._start_library_restore_task(self.uploaded_zip_file)
|
||||
@@ -1202,7 +1202,7 @@ class LibraryRestoreViewTestCase(ContentLibrariesRestApiTest):
|
||||
"""
|
||||
with self.as_user(self.admin_user):
|
||||
with patch(
|
||||
"openedx.core.djangoapps.content_libraries.tasks.authoring_api.load_learning_package",
|
||||
"openedx.core.djangoapps.content_libraries.tasks.content_api.load_learning_package",
|
||||
side_effect=Exception("Uncaught exception during processing.")
|
||||
):
|
||||
response = self._start_library_restore_task(self.uploaded_zip_file)
|
||||
|
||||
@@ -5,7 +5,7 @@ Tests Library Collections REST API views
|
||||
from __future__ import annotations
|
||||
import ddt
|
||||
|
||||
from openedx_learning.api.authoring_models import Collection
|
||||
from openedx_content.models_api import Collection
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
|
||||
from openedx.core.djangolib.testing.utils import skip_unless_cms
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Generated by Django 3.2.23 on 2023-12-07 20:10
|
||||
|
||||
from django.db import migrations
|
||||
import openedx_learning.lib.fields
|
||||
import openedx_django_lib.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@@ -14,11 +14,11 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='stagedcontent',
|
||||
name='display_name',
|
||||
field=openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, max_length=768),
|
||||
field=openedx_django_lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, max_length=768),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='stagedcontent',
|
||||
name='olx',
|
||||
field=openedx_learning.lib.fields.MultiCollationTextField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}),
|
||||
field=openedx_django_lib.fields.MultiCollationTextField(db_collations={'mysql': 'utf8mb4_bin', 'sqlite': 'BINARY'}),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import ContainerKey, LearningContextKey, UsageKey
|
||||
from openedx_learning.lib.fields import MultiCollationTextField, case_insensitive_char_field
|
||||
from openedx_django_lib.fields import MultiCollationTextField, case_insensitive_char_field
|
||||
|
||||
from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ import csv
|
||||
from typing import Iterator
|
||||
from opaque_keys.edx.keys import CourseKey, CollectionKey, ContainerKey, UsageKey
|
||||
|
||||
import openedx_tagging.core.tagging.api as oel_tagging
|
||||
import openedx_tagging.api as oel_tagging
|
||||
from django.db.models import Exists, OuterRef, Q, QuerySet
|
||||
from django.utils.timezone import now
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_tagging.core.tagging.models import ObjectTag, Taxonomy
|
||||
from openedx_tagging.core.tagging.models.utils import TAGS_CSV_SEPARATOR
|
||||
from openedx_tagging.models import ObjectTag, Taxonomy
|
||||
from openedx_tagging.models.utils import TAGS_CSV_SEPARATOR
|
||||
from organizations.models import Organization
|
||||
from .helpers.objecttag_export_helpers import build_object_tree_with_objecttags, iterate_with_level
|
||||
from openedx_events.content_authoring.data import ContentObjectData, ContentObjectChangedData
|
||||
|
||||
@@ -3,7 +3,7 @@ Functions to validate the access in content tagging actions
|
||||
"""
|
||||
|
||||
|
||||
from openedx_tagging.core.tagging import rules as oel_tagging_rules
|
||||
from openedx_tagging import rules as oel_tagging_rules
|
||||
|
||||
|
||||
def has_view_object_tags_access(user, object_id):
|
||||
|
||||
@@ -6,7 +6,7 @@ from __future__ import annotations
|
||||
from django.db import models
|
||||
from django.db.models import Q, QuerySet
|
||||
from django.utils.translation import gettext as _
|
||||
from openedx_tagging.core.tagging.models import Taxonomy
|
||||
from openedx_tagging.models import Taxonomy
|
||||
from organizations.models import Organization
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ API Filters for content tagging org
|
||||
from django.db.models import Exists, OuterRef, Q
|
||||
from rest_framework.filters import BaseFilterBackend
|
||||
|
||||
import openedx_tagging.core.tagging.rules as oel_tagging
|
||||
import openedx_tagging.rules as oel_tagging
|
||||
|
||||
from ...rules import get_admin_orgs, get_user_orgs
|
||||
from ...models import TaxonomyOrg
|
||||
|
||||
@@ -6,7 +6,7 @@ from __future__ import annotations
|
||||
|
||||
from rest_framework import serializers, fields
|
||||
|
||||
from openedx_tagging.core.tagging.rest_api.v1.serializers import (
|
||||
from openedx_tagging.rest_api.v1.serializers import (
|
||||
ObjectTagMinimalSerializer,
|
||||
TaxonomyListQueryParamsSerializer,
|
||||
TaxonomySerializer,
|
||||
|
||||
@@ -15,9 +15,9 @@ from django.contrib.auth import get_user_model
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from edx_django_utils.cache import RequestCache
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryCollectionLocator, LibraryContainerLocator
|
||||
from openedx_tagging.core.tagging.models import Tag, Taxonomy
|
||||
from openedx_tagging.core.tagging.models.system_defined import SystemDefinedTaxonomy
|
||||
from openedx_tagging.core.tagging.rest_api.v1.serializers import TaxonomySerializer
|
||||
from openedx_tagging.models import Tag, Taxonomy
|
||||
from openedx_tagging.models.system_defined import SystemDefinedTaxonomy
|
||||
from openedx_tagging.rest_api.v1.serializers import TaxonomySerializer
|
||||
from organizations.models import Organization
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
@@ -3,9 +3,9 @@ Taxonomies API v1 URLs.
|
||||
"""
|
||||
|
||||
from django.urls.conf import include, path
|
||||
from openedx_tagging.core.tagging.rest_api.v1 import views as oel_tagging_views
|
||||
from openedx_tagging.core.tagging.rest_api.v1 import views_import as oel_tagging_views_import
|
||||
from openedx_tagging.core.tagging.rest_api.v1.views import ObjectTagCountsView
|
||||
from openedx_tagging.rest_api.v1 import views as oel_tagging_views
|
||||
from openedx_tagging.rest_api.v1 import views_import as oel_tagging_views_import
|
||||
from openedx_tagging.rest_api.v1.views import ObjectTagCountsView
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
from . import views
|
||||
|
||||
@@ -5,8 +5,8 @@ from __future__ import annotations
|
||||
|
||||
from django.db.models import Count
|
||||
from django.http import StreamingHttpResponse
|
||||
from openedx_tagging.core.tagging import rules as oel_tagging_rules
|
||||
from openedx_tagging.core.tagging.rest_api.v1.views import ObjectTagView, TaxonomyView
|
||||
from openedx_tagging import rules as oel_tagging_rules
|
||||
from openedx_tagging.rest_api.v1.views import ObjectTagView, TaxonomyView
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import PermissionDenied, ValidationError
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
from typing import Union
|
||||
|
||||
import django.contrib.auth.models
|
||||
import openedx_tagging.core.tagging.rules as oel_tagging
|
||||
import openedx_tagging.rules as oel_tagging
|
||||
import rules
|
||||
from organizations.models import Organization
|
||||
|
||||
|
||||
@@ -12,7 +12,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 CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import LibraryUsageLocatorV2
|
||||
from openedx_tagging.core.tagging.models import Taxonomy
|
||||
from openedx_tagging.models import Taxonomy
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.test.testcases import TestCase
|
||||
from fs.osfs import OSFS
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2, LibraryCollectionLocator, LibraryContainerLocator
|
||||
from openedx_tagging.core.tagging.models import ObjectTag
|
||||
from openedx_tagging.models import ObjectTag
|
||||
from organizations.models import Organization
|
||||
from .test_objecttag_export_helpers import TestGetAllObjectTagsMixin, TaggedCourseMixin
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Test the objecttag_export_helpers module
|
||||
import time
|
||||
from unittest.mock import patch
|
||||
|
||||
from openedx_tagging.core.tagging.models import ObjectTag
|
||||
from openedx_tagging.models import ObjectTag
|
||||
from organizations.models import Organization
|
||||
|
||||
from openedx.core.djangoapps.content_libraries import api as library_api
|
||||
|
||||
@@ -4,11 +4,11 @@ import ddt
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
||||
from openedx_tagging.core.tagging.models import (
|
||||
from openedx_tagging.models import (
|
||||
Tag,
|
||||
UserSystemDefinedTaxonomy,
|
||||
)
|
||||
from openedx_tagging.core.tagging.rules import ObjectTagPermissionItem
|
||||
from openedx_tagging.rules import ObjectTagPermissionItem
|
||||
|
||||
from common.djangoapps.student.auth import add_users, update_org_role
|
||||
from common.djangoapps.student.roles import CourseStaffRole, OrgStaffRole
|
||||
|
||||
@@ -8,7 +8,7 @@ from unittest.mock import patch
|
||||
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, ObjectTag
|
||||
from openedx_tagging.models import Tag, Taxonomy, ObjectTag
|
||||
from organizations.models import Organization
|
||||
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
@@ -41,9 +41,9 @@ class LanguageTaxonomyTestMixin:
|
||||
running migrations. So data created by our migrations is not present.
|
||||
In particular, the Language Taxonomy is not present. So this mixin will
|
||||
create the taxonomy, simulating the effect of the following migrations:
|
||||
1. openedx_tagging.core.tagging.migrations.0012_language_taxonomy
|
||||
1. openedx_tagging.migrations.0012_language_taxonomy
|
||||
2. content_tagging.migrations.0007_system_defined_org_2
|
||||
3. openedx_tagging.core.tagging.migrations.0015_taxonomy_export_id
|
||||
3. openedx_tagging.migrations.0015_taxonomy_export_id
|
||||
"""
|
||||
super().setUp()
|
||||
Taxonomy.objects.get_or_create(id=-1, defaults={
|
||||
@@ -54,7 +54,7 @@ class LanguageTaxonomyTestMixin:
|
||||
"allow_free_text": False,
|
||||
"visible_to_authors": True,
|
||||
"export_id": "-1_languages",
|
||||
"_taxonomy_class": "openedx_tagging.core.tagging.models.system_defined.LanguageTaxonomy",
|
||||
"_taxonomy_class": "openedx_tagging.models.system_defined.LanguageTaxonomy",
|
||||
})
|
||||
TaxonomyOrg.objects.get_or_create(taxonomy_id=-1, defaults={"org": None})
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from typing import Dict, List, Union
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey, CollectionKey, ContainerKey
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_tagging.core.tagging.models import Taxonomy
|
||||
from openedx_tagging.models import Taxonomy
|
||||
|
||||
ContentKey = Union[LibraryLocatorV2, CourseKey, UsageKey, CollectionKey, ContainerKey]
|
||||
ContextKey = Union[LibraryLocatorV2, CourseKey]
|
||||
|
||||
@@ -7,7 +7,7 @@ from edx_django_utils.cache import RequestCache
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.keys import CourseKey, CollectionKey, ContainerKey, UsageKey
|
||||
from opaque_keys.edx.locator import LibraryLocatorV2
|
||||
from openedx_tagging.core.tagging.models import Taxonomy
|
||||
from openedx_tagging.models import Taxonomy
|
||||
from organizations.models import Organization
|
||||
|
||||
from .models import TaxonomyOrg
|
||||
|
||||
@@ -16,8 +16,8 @@ import threading
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_learning.api.authoring_models import Component, ComponentVersion
|
||||
from openedx_content import api as content_api
|
||||
from openedx_content.models_api import Component, ComponentVersion
|
||||
from opaque_keys.edx.keys import UsageKeyV2
|
||||
from opaque_keys.edx.locator import LibraryUsageLocatorV2
|
||||
from rest_framework.exceptions import NotFound
|
||||
@@ -202,10 +202,10 @@ def get_component_from_usage_key(usage_key: UsageKeyV2) -> Component:
|
||||
This is a lower-level function that will return a Component even if there is
|
||||
no current draft version of that Component (because it's been soft-deleted).
|
||||
"""
|
||||
learning_package = authoring_api.get_learning_package_by_key(
|
||||
learning_package = content_api.get_learning_package_by_key(
|
||||
str(usage_key.context_key)
|
||||
)
|
||||
return authoring_api.get_component_by_key(
|
||||
return content_api.get_component_by_key(
|
||||
learning_package.id,
|
||||
namespace='xblock.v1',
|
||||
type_name=usage_key.block_type,
|
||||
|
||||
@@ -12,7 +12,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.db.transaction import atomic
|
||||
from django.urls import reverse
|
||||
|
||||
from openedx_learning.api import authoring as authoring_api
|
||||
from openedx_content import api as content_api
|
||||
|
||||
from lxml import etree
|
||||
|
||||
@@ -295,16 +295,16 @@ class LearningCoreXBlockRuntime(XBlockRuntime):
|
||||
usage_key = block.scope_ids.usage_id
|
||||
with atomic():
|
||||
component = self._get_component_from_usage_key(usage_key)
|
||||
block_media_type = authoring_api.get_or_create_media_type(
|
||||
block_media_type = content_api.get_or_create_media_type(
|
||||
f"application/vnd.openedx.xblock.v1.{usage_key.block_type}+xml"
|
||||
)
|
||||
content = authoring_api.get_or_create_text_content(
|
||||
content = content_api.get_or_create_text_content(
|
||||
component.learning_package_id,
|
||||
block_media_type.id,
|
||||
text=serialized.olx_str,
|
||||
created=now,
|
||||
)
|
||||
authoring_api.create_next_version(
|
||||
content_api.create_next_component_version(
|
||||
component.pk,
|
||||
title=block.display_name,
|
||||
content_to_replace={
|
||||
@@ -329,9 +329,9 @@ class LearningCoreXBlockRuntime(XBlockRuntime):
|
||||
TODO: This is the third place where we're implementing this. Figure out
|
||||
where the definitive place should be and have everything else call that.
|
||||
"""
|
||||
learning_package = authoring_api.get_learning_package_by_key(str(usage_key.lib_key))
|
||||
learning_package = content_api.get_learning_package_by_key(str(usage_key.lib_key))
|
||||
try:
|
||||
component = authoring_api.get_component_by_key(
|
||||
component = content_api.get_component_by_key(
|
||||
learning_package.id,
|
||||
namespace='xblock.v1',
|
||||
type_name=usage_key.block_type,
|
||||
|
||||
@@ -8,7 +8,7 @@ from xmodule.modulestore.django import contentstore, modulestore
|
||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, upload_file_to_course
|
||||
from xmodule.modulestore.tests.factories import BlockFactory, CourseFactory, ToyCourseFactory, LibraryFactory
|
||||
from xmodule.util.sandboxing import DEFAULT_PYTHON_LIB_FILENAME
|
||||
from openedx_tagging.core.tagging.models import Tag
|
||||
from openedx_tagging.models import Tag
|
||||
from openedx.core.djangoapps.content_tagging.models import TaxonomyOrg
|
||||
from openedx.core.djangoapps.content_tagging import api as tagging_api
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ numpy<2.0.0
|
||||
# Date: 2023-09-18
|
||||
# pinning this version to avoid updates while the library is being developed
|
||||
# Issue for unpinning: https://github.com/openedx/edx-platform/issues/35269
|
||||
openedx-learning==0.31.0
|
||||
openedx-learning==0.32.0
|
||||
|
||||
# Date: 2023-11-29
|
||||
# Open AI version 1.0.0 dropped support for openai.ChatCompletion which is currently in use in enterprise.
|
||||
@@ -146,4 +146,3 @@ pact-python<3.0.0
|
||||
# building requirements with Python 3.12
|
||||
# https://github.com/openedx/edx-platform/issues/37880
|
||||
sphinx-autoapi<3.6.1
|
||||
|
||||
|
||||
@@ -832,7 +832,7 @@ openedx-filters==2.1.0
|
||||
# ora2
|
||||
openedx-forum==0.4.0
|
||||
# via -r requirements/edx/kernel.in
|
||||
openedx-learning==0.31.0
|
||||
openedx-learning==0.32.0
|
||||
# via
|
||||
# -c requirements/constraints.txt
|
||||
# -r requirements/edx/kernel.in
|
||||
|
||||
@@ -1399,7 +1399,7 @@ openedx-forum==0.4.0
|
||||
# via
|
||||
# -r requirements/edx/doc.txt
|
||||
# -r requirements/edx/testing.txt
|
||||
openedx-learning==0.31.0
|
||||
openedx-learning==0.32.0
|
||||
# via
|
||||
# -c requirements/constraints.txt
|
||||
# -r requirements/edx/doc.txt
|
||||
|
||||
@@ -1009,7 +1009,7 @@ openedx-filters==2.1.0
|
||||
# ora2
|
||||
openedx-forum==0.4.0
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-learning==0.31.0
|
||||
openedx-learning==0.32.0
|
||||
# via
|
||||
# -c requirements/constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
|
||||
@@ -1059,7 +1059,7 @@ openedx-filters==2.1.0
|
||||
# ora2
|
||||
openedx-forum==0.4.0
|
||||
# via -r requirements/edx/base.txt
|
||||
openedx-learning==0.31.0
|
||||
openedx-learning==0.32.0
|
||||
# via
|
||||
# -c requirements/constraints.txt
|
||||
# -r requirements/edx/base.txt
|
||||
|
||||
@@ -60,7 +60,7 @@ root_packages =
|
||||
lms
|
||||
cms
|
||||
openedx
|
||||
openedx_learning
|
||||
openedx_content
|
||||
include_external_packages = True
|
||||
contract_types =
|
||||
# Our custom contract which checks that we're only importing from 'api.py'
|
||||
@@ -193,14 +193,17 @@ allowed_modules =
|
||||
tests
|
||||
|
||||
[importlinter:contract:3]
|
||||
name = Do not import apps from openedx-learning (only import from openedx_learning.api.* and openedx_learning.lib.*).
|
||||
name = Do not directly import internals of openedx_content (only import from openedx_content.api).
|
||||
type = forbidden
|
||||
source_modules =
|
||||
cms
|
||||
lms
|
||||
openedx
|
||||
common
|
||||
xmodule
|
||||
forbidden_modules =
|
||||
openedx_learning.apps
|
||||
openedx_content.applets
|
||||
openedx_content.backcompat
|
||||
allow_indirect_imports = True
|
||||
|
||||
[importlinter:contract:4]
|
||||
|
||||
Reference in New Issue
Block a user