openedx-learning 0.30.1__py2.py3-none-any.whl → 0.31.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openedx_learning/__init__.py +1 -1
- openedx_learning/api/authoring.py +2 -9
- openedx_learning/api/authoring_models.py +7 -7
- openedx_learning/api/django.py +24 -0
- openedx_learning/apps/openedx_content/admin.py +13 -0
- openedx_learning/apps/openedx_content/api.py +16 -0
- openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/api.py +2 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/serializers.py +1 -4
- openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/toml.py +4 -4
- openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/zipper.py +28 -14
- openedx_learning/apps/{authoring → openedx_content/applets}/collections/api.py +1 -1
- openedx_learning/apps/{authoring → openedx_content/applets}/collections/models.py +4 -1
- openedx_learning/apps/{authoring → openedx_content/applets}/components/admin.py +1 -1
- openedx_learning/apps/{authoring → openedx_content/applets}/components/api.py +1 -1
- openedx_learning/apps/{authoring → openedx_content/applets}/components/models.py +4 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/contents/api.py +3 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/contents/models.py +8 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/publishing/api.py +1 -1
- openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/entity_list.py +1 -0
- openedx_learning/apps/{authoring → openedx_content/applets}/sections/api.py +1 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/subsections/api.py +1 -2
- openedx_learning/apps/{authoring → openedx_content/applets}/units/api.py +1 -2
- openedx_learning/apps/openedx_content/apps.py +52 -0
- openedx_learning/apps/{authoring → openedx_content/backcompat}/backup_restore/apps.py +1 -1
- openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/apps.py +1 -1
- openedx_learning/apps/openedx_content/backcompat/collections/migrations/0006_remove_all_field_state_for_move_to_applet.py +82 -0
- openedx_learning/apps/openedx_content/backcompat/collections/models.py +9 -0
- openedx_learning/apps/openedx_content/backcompat/components/apps.py +15 -0
- openedx_learning/apps/openedx_content/backcompat/components/migrations/0005_remove_all_field_state_for_move_to_applet.py +72 -0
- openedx_learning/apps/openedx_content/backcompat/components/models.py +11 -0
- openedx_learning/apps/{authoring → openedx_content/backcompat}/contents/apps.py +1 -1
- openedx_learning/apps/openedx_content/backcompat/contents/migrations/0002_remove_all_field_state_for_move_to_applet.py +26 -0
- openedx_learning/apps/openedx_content/backcompat/publishing/apps.py +15 -0
- openedx_learning/apps/openedx_content/backcompat/publishing/migrations/0010_backfill_dependencies.py +432 -0
- openedx_learning/apps/openedx_content/backcompat/publishing/migrations/0011_remove_all_field_state_for_move_to_applet.py +288 -0
- openedx_learning/apps/openedx_content/backcompat/publishing/models.py +27 -0
- openedx_learning/apps/openedx_content/backcompat/sections/__init__.py +0 -0
- openedx_learning/apps/openedx_content/backcompat/sections/apps.py +16 -0
- openedx_learning/apps/openedx_content/backcompat/sections/migrations/0002_remove_all_field_state_for_move_to_applet.py +29 -0
- openedx_learning/apps/openedx_content/backcompat/sections/migrations/__init__.py +0 -0
- openedx_learning/apps/openedx_content/backcompat/subsections/__init__.py +0 -0
- openedx_learning/apps/openedx_content/backcompat/subsections/apps.py +16 -0
- openedx_learning/apps/openedx_content/backcompat/subsections/migrations/0002_remove_all_field_state_for_move_to_applet.py +29 -0
- openedx_learning/apps/openedx_content/backcompat/subsections/migrations/__init__.py +0 -0
- openedx_learning/apps/openedx_content/backcompat/units/__init__.py +0 -0
- openedx_learning/apps/openedx_content/backcompat/units/apps.py +16 -0
- openedx_learning/apps/openedx_content/backcompat/units/migrations/0002_remove_all_field_state_for_move_to_applet.py +29 -0
- openedx_learning/apps/openedx_content/backcompat/units/migrations/__init__.py +0 -0
- openedx_learning/apps/openedx_content/management/__init__.py +0 -0
- openedx_learning/apps/openedx_content/management/commands/__init__.py +0 -0
- openedx_learning/apps/{authoring/components → openedx_content}/management/commands/add_assets_to_component.py +1 -2
- openedx_learning/apps/{authoring/backup_restore → openedx_content}/management/commands/lp_dump.py +2 -2
- openedx_learning/apps/{authoring/backup_restore → openedx_content}/management/commands/lp_load.py +1 -1
- openedx_learning/apps/openedx_content/migrations/0001_initial.py +654 -0
- openedx_learning/apps/openedx_content/migrations/0002_rename_tables_to_openedx_content.py +138 -0
- openedx_learning/apps/openedx_content/migrations/__init__.py +0 -0
- openedx_learning/apps/openedx_content/models.py +17 -0
- openedx_learning/contrib/media_server/views.py +1 -1
- {openedx_learning-0.30.1.dist-info → openedx_learning-0.31.0.dist-info}/METADATA +6 -6
- openedx_learning-0.31.0.dist-info/RECORD +194 -0
- {openedx_learning-0.30.1.dist-info → openedx_learning-0.31.0.dist-info}/WHEEL +1 -1
- openedx_learning/apps/authoring/components/apps.py +0 -24
- openedx_learning/apps/authoring/publishing/apps.py +0 -25
- openedx_learning/apps/authoring/publishing/migrations/0010_backfill_dependencies.py +0 -149
- openedx_learning/apps/authoring/sections/apps.py +0 -25
- openedx_learning/apps/authoring/subsections/apps.py +0 -25
- openedx_learning/apps/authoring/units/apps.py +0 -25
- openedx_learning-0.30.1.dist-info/RECORD +0 -168
- /openedx_learning/apps/{authoring → openedx_content}/__init__.py +0 -0
- /openedx_learning/apps/{authoring/backup_restore → openedx_content/applets}/__init__.py +0 -0
- /openedx_learning/apps/{authoring/backup_restore/management → openedx_content/applets/backup_restore}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/admin.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/backup_restore/models.py +0 -0
- /openedx_learning/apps/{authoring/backup_restore/management/commands → openedx_content/applets/collections}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/collections/admin.py +0 -0
- /openedx_learning/apps/{authoring/backup_restore/migrations → openedx_content/applets/components}/__init__.py +0 -0
- /openedx_learning/apps/{authoring/collections → openedx_content/applets/contents}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/contents/admin.py +0 -0
- /openedx_learning/apps/{authoring/collections/migrations → openedx_content/applets/publishing}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/admin.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/contextmanagers.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/container.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/draft_log.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/learning_package.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/publish_log.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/publishing/models/publishable_entity.py +0 -0
- /openedx_learning/apps/{authoring/components → openedx_content/applets/sections}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/sections/admin.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/sections/models.py +0 -0
- /openedx_learning/apps/{authoring/components/management → openedx_content/applets/subsections}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/subsections/admin.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/subsections/models.py +0 -0
- /openedx_learning/apps/{authoring/components/management/commands → openedx_content/applets/units}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/units/admin.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/applets}/units/models.py +0 -0
- /openedx_learning/apps/{authoring/components/migrations → openedx_content/backcompat}/__init__.py +0 -0
- /openedx_learning/apps/{authoring/contents → openedx_content/backcompat/backup_restore}/__init__.py +0 -0
- /openedx_learning/apps/{authoring/contents → openedx_content/backcompat/backup_restore}/migrations/__init__.py +0 -0
- /openedx_learning/apps/{authoring/publishing → openedx_content/backcompat/collections}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/migrations/0002_remove_collection_name_collection_created_by_and_more.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/migrations/0003_collection_entities.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/migrations/0004_collection_key.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/collections/migrations/0005_alter_collection_options_alter_collection_enabled.py +0 -0
- /openedx_learning/apps/{authoring/publishing → openedx_content/backcompat/collections}/migrations/__init__.py +0 -0
- /openedx_learning/apps/{authoring/sections → openedx_content/backcompat/components}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/components/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/components/migrations/0002_alter_componentversioncontent_key.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/components/migrations/0003_remove_componentversioncontent_learner_downloadable.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/components/migrations/0004_remove_componentversioncontent_uuid.py +0 -0
- /openedx_learning/apps/{authoring/sections → openedx_content/backcompat/components}/migrations/__init__.py +0 -0
- /openedx_learning/apps/{authoring/subsections → openedx_content/backcompat/contents}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/contents/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring/subsections → openedx_content/backcompat/contents}/migrations/__init__.py +0 -0
- /openedx_learning/apps/{authoring/units → openedx_content/backcompat/publishing}/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0002_alter_learningpackage_key_and_more.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0003_containers.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0004_publishableentity_can_stand_alone.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0005_alter_entitylistrow_options.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0006_draftchangelog.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0007_bootstrap_draftchangelog.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0008_alter_draftchangelogrecord_options_and_more.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/publishing/migrations/0009_dependencies_and_hashing.py +0 -0
- /openedx_learning/apps/{authoring/units → openedx_content/backcompat/publishing}/migrations/__init__.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/sections/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/subsections/migrations/0001_initial.py +0 -0
- /openedx_learning/apps/{authoring → openedx_content/backcompat}/units/migrations/0001_initial.py +0 -0
- {openedx_learning-0.30.1.dist-info → openedx_learning-0.31.0.dist-info}/licenses/LICENSE.txt +0 -0
- {openedx_learning-0.30.1.dist-info → openedx_learning-0.31.0.dist-info}/top_level.txt +0 -0
openedx_learning/__init__.py
CHANGED
|
@@ -2,21 +2,14 @@
|
|
|
2
2
|
This is the public API for content authoring in Learning Core.
|
|
3
3
|
|
|
4
4
|
This is the single ``api`` module that code outside of the
|
|
5
|
-
``openedx_learning.apps.
|
|
5
|
+
``openedx_learning.apps.openedx_content.*`` package should import from. It will
|
|
6
6
|
re-export the public functions from all api.py modules of all authoring apps. It
|
|
7
7
|
may also implement its own convenience APIs that wrap calls to multiple app
|
|
8
8
|
APIs.
|
|
9
9
|
"""
|
|
10
10
|
# These wildcard imports are okay because these api modules declare __all__.
|
|
11
11
|
# pylint: disable=wildcard-import
|
|
12
|
-
from ..apps.
|
|
13
|
-
from ..apps.authoring.collections.api import *
|
|
14
|
-
from ..apps.authoring.components.api import *
|
|
15
|
-
from ..apps.authoring.contents.api import *
|
|
16
|
-
from ..apps.authoring.publishing.api import *
|
|
17
|
-
from ..apps.authoring.sections.api import *
|
|
18
|
-
from ..apps.authoring.subsections.api import *
|
|
19
|
-
from ..apps.authoring.units.api import *
|
|
12
|
+
from ..apps.openedx_content.api import *
|
|
20
13
|
|
|
21
14
|
# This was renamed after the authoring API refactoring pushed this and other
|
|
22
15
|
# app APIs into the openedx_learning.api.authoring module. Here I'm aliasing to
|
|
@@ -7,10 +7,10 @@ consistent.
|
|
|
7
7
|
"""
|
|
8
8
|
# These wildcard imports are okay because these modules declare __all__.
|
|
9
9
|
# pylint: disable=wildcard-import
|
|
10
|
-
from ..apps.
|
|
11
|
-
from ..apps.
|
|
12
|
-
from ..apps.
|
|
13
|
-
from ..apps.
|
|
14
|
-
from ..apps.
|
|
15
|
-
from ..apps.
|
|
16
|
-
from ..apps.
|
|
10
|
+
from ..apps.openedx_content.applets.collections.models import *
|
|
11
|
+
from ..apps.openedx_content.applets.components.models import *
|
|
12
|
+
from ..apps.openedx_content.applets.contents.models import *
|
|
13
|
+
from ..apps.openedx_content.applets.publishing.models import *
|
|
14
|
+
from ..apps.openedx_content.applets.sections.models import *
|
|
15
|
+
from ..apps.openedx_content.applets.subsections.models import *
|
|
16
|
+
from ..apps.openedx_content.applets.units.models import *
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for parts of the Learning Core API that exist to make it easier to use in
|
|
3
|
+
Django projects.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def openedx_learning_apps_to_install():
|
|
8
|
+
"""
|
|
9
|
+
Return all app names for appending to INSTALLED_APPS.
|
|
10
|
+
|
|
11
|
+
This function exists to better insulate edx-platform and potential plugins
|
|
12
|
+
over time, as we eventually plan to remove the backcompat apps.
|
|
13
|
+
"""
|
|
14
|
+
return [
|
|
15
|
+
"openedx_learning.apps.openedx_content",
|
|
16
|
+
"openedx_learning.apps.openedx_content.backcompat.backup_restore",
|
|
17
|
+
"openedx_learning.apps.openedx_content.backcompat.collections",
|
|
18
|
+
"openedx_learning.apps.openedx_content.backcompat.components",
|
|
19
|
+
"openedx_learning.apps.openedx_content.backcompat.contents",
|
|
20
|
+
"openedx_learning.apps.openedx_content.backcompat.publishing",
|
|
21
|
+
"openedx_learning.apps.openedx_content.backcompat.sections",
|
|
22
|
+
"openedx_learning.apps.openedx_content.backcompat.subsections",
|
|
23
|
+
"openedx_learning.apps.openedx_content.backcompat.units",
|
|
24
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module aggregates all applet Django Admin modules.
|
|
3
|
+
"""
|
|
4
|
+
# pylint: disable=wildcard-import
|
|
5
|
+
|
|
6
|
+
from .applets.backup_restore.admin import *
|
|
7
|
+
from .applets.collections.admin import *
|
|
8
|
+
from .applets.components.admin import *
|
|
9
|
+
from .applets.contents.admin import *
|
|
10
|
+
from .applets.publishing.admin import *
|
|
11
|
+
from .applets.sections.admin import *
|
|
12
|
+
from .applets.subsections.admin import *
|
|
13
|
+
from .applets.units.admin import *
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module aggregates all applet API modules.
|
|
3
|
+
|
|
4
|
+
Question: Should this replace openedx_learning.api.authoring?
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# pylint: disable=wildcard-import
|
|
8
|
+
|
|
9
|
+
from .applets.backup_restore.api import *
|
|
10
|
+
from .applets.collections.api import *
|
|
11
|
+
from .applets.components.api import *
|
|
12
|
+
from .applets.contents.api import *
|
|
13
|
+
from .applets.publishing.api import *
|
|
14
|
+
from .applets.sections.api import *
|
|
15
|
+
from .applets.subsections.api import *
|
|
16
|
+
from .applets.units.api import *
|
|
@@ -5,8 +5,8 @@ import zipfile
|
|
|
5
5
|
|
|
6
6
|
from django.contrib.auth.models import User as UserType # pylint: disable=imported-auth-user
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from ..publishing.api import get_learning_package_by_key
|
|
9
|
+
from .zipper import LearningPackageUnzipper, LearningPackageZipper
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def create_zip_file(lp_key: str, path: str, user: UserType | None = None, origin_server: str | None = None) -> None:
|
|
@@ -5,7 +5,7 @@ from datetime import timezone
|
|
|
5
5
|
|
|
6
6
|
from rest_framework import serializers
|
|
7
7
|
|
|
8
|
-
from
|
|
8
|
+
from ..components import api as components_api
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LearningPackageSerializer(serializers.Serializer): # pylint: disable=abstract-method
|
|
@@ -44,7 +44,6 @@ class EntitySerializer(serializers.Serializer): # pylint: disable=abstract-meth
|
|
|
44
44
|
can_stand_alone = serializers.BooleanField(required=True)
|
|
45
45
|
key = serializers.CharField(required=True)
|
|
46
46
|
created = serializers.DateTimeField(required=True, default_timezone=timezone.utc)
|
|
47
|
-
created_by = serializers.CharField(required=True, allow_null=True)
|
|
48
47
|
|
|
49
48
|
|
|
50
49
|
class EntityVersionSerializer(serializers.Serializer): # pylint: disable=abstract-method
|
|
@@ -54,7 +53,6 @@ class EntityVersionSerializer(serializers.Serializer): # pylint: disable=abstra
|
|
|
54
53
|
title = serializers.CharField(required=True)
|
|
55
54
|
entity_key = serializers.CharField(required=True)
|
|
56
55
|
created = serializers.DateTimeField(required=True, default_timezone=timezone.utc)
|
|
57
|
-
created_by = serializers.CharField(required=True, allow_null=True)
|
|
58
56
|
version_num = serializers.IntegerField(required=True)
|
|
59
57
|
|
|
60
58
|
|
|
@@ -160,7 +158,6 @@ class CollectionSerializer(serializers.Serializer): # pylint: disable=abstract-
|
|
|
160
158
|
title = serializers.CharField(required=True)
|
|
161
159
|
key = serializers.CharField(required=True)
|
|
162
160
|
description = serializers.CharField(required=True, allow_blank=True)
|
|
163
|
-
created_by = serializers.IntegerField(required=True, allow_null=True)
|
|
164
161
|
entities = serializers.ListField(
|
|
165
162
|
child=serializers.CharField(),
|
|
166
163
|
required=True,
|
|
@@ -8,10 +8,10 @@ from typing import Any, Dict
|
|
|
8
8
|
import tomlkit
|
|
9
9
|
from django.contrib.auth.models import User as UserType # pylint: disable=imported-auth-user
|
|
10
10
|
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
11
|
+
from ..collections.models import Collection
|
|
12
|
+
from ..publishing import api as publishing_api
|
|
13
|
+
from ..publishing.models import PublishableEntity, PublishableEntityVersion
|
|
14
|
+
from ..publishing.models.learning_package import LearningPackage
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def toml_learning_package(
|
|
@@ -28,7 +28,15 @@ from openedx_learning.api.authoring_models import (
|
|
|
28
28
|
PublishableEntity,
|
|
29
29
|
PublishableEntityVersion,
|
|
30
30
|
)
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
from ..collections import api as collections_api
|
|
33
|
+
from ..components import api as components_api
|
|
34
|
+
from ..contents import api as contents_api
|
|
35
|
+
from ..publishing import api as publishing_api
|
|
36
|
+
from ..sections import api as sections_api
|
|
37
|
+
from ..subsections import api as subsections_api
|
|
38
|
+
from ..units import api as units_api
|
|
39
|
+
from .serializers import (
|
|
32
40
|
CollectionSerializer,
|
|
33
41
|
ComponentSerializer,
|
|
34
42
|
ComponentVersionSerializer,
|
|
@@ -37,7 +45,7 @@ from openedx_learning.apps.authoring.backup_restore.serializers import (
|
|
|
37
45
|
LearningPackageMetadataSerializer,
|
|
38
46
|
LearningPackageSerializer,
|
|
39
47
|
)
|
|
40
|
-
from
|
|
48
|
+
from .toml import (
|
|
41
49
|
parse_collection_toml,
|
|
42
50
|
parse_learning_package_toml,
|
|
43
51
|
parse_publishable_entity_toml,
|
|
@@ -45,13 +53,6 @@ from openedx_learning.apps.authoring.backup_restore.toml import (
|
|
|
45
53
|
toml_learning_package,
|
|
46
54
|
toml_publishable_entity,
|
|
47
55
|
)
|
|
48
|
-
from openedx_learning.apps.authoring.collections import api as collections_api
|
|
49
|
-
from openedx_learning.apps.authoring.components import api as components_api
|
|
50
|
-
from openedx_learning.apps.authoring.contents import api as contents_api
|
|
51
|
-
from openedx_learning.apps.authoring.publishing import api as publishing_api
|
|
52
|
-
from openedx_learning.apps.authoring.sections import api as sections_api
|
|
53
|
-
from openedx_learning.apps.authoring.subsections import api as subsections_api
|
|
54
|
-
from openedx_learning.apps.authoring.units import api as units_api
|
|
55
56
|
|
|
56
57
|
TOML_PACKAGE_NAME = "package.toml"
|
|
57
58
|
DEFAULT_USERNAME = "command"
|
|
@@ -508,6 +509,7 @@ class LearningPackageUnzipper:
|
|
|
508
509
|
def __init__(self, zipf: zipfile.ZipFile, key: str | None = None, user: UserType | None = None):
|
|
509
510
|
self.zipf = zipf
|
|
510
511
|
self.user = user
|
|
512
|
+
self.user_id = getattr(self.user, "id", None)
|
|
511
513
|
self.lp_key = key # If provided, use this key for the restored learning package
|
|
512
514
|
self.learning_package_id: int | None = None # Will be set upon restoration
|
|
513
515
|
self.utc_now: datetime = datetime.now(timezone.utc)
|
|
@@ -771,7 +773,9 @@ class LearningPackageUnzipper:
|
|
|
771
773
|
"""Save collections and their entities."""
|
|
772
774
|
for valid_collection in collections.get("collections", []):
|
|
773
775
|
entities = valid_collection.pop("entities", [])
|
|
774
|
-
collection = collections_api.create_collection(
|
|
776
|
+
collection = collections_api.create_collection(
|
|
777
|
+
learning_package.id, created_by=self.user_id, **valid_collection
|
|
778
|
+
)
|
|
775
779
|
collection = collections_api.add_to_collection(
|
|
776
780
|
learning_package_id=learning_package.id,
|
|
777
781
|
key=collection.key,
|
|
@@ -782,7 +786,7 @@ class LearningPackageUnzipper:
|
|
|
782
786
|
"""Save components and published component versions."""
|
|
783
787
|
for valid_component in components.get("components", []):
|
|
784
788
|
entity_key = valid_component.pop("key")
|
|
785
|
-
component = components_api.create_component(learning_package.id, **valid_component)
|
|
789
|
+
component = components_api.create_component(learning_package.id, created_by=self.user_id, **valid_component)
|
|
786
790
|
self.components_map_by_key[entity_key] = component
|
|
787
791
|
|
|
788
792
|
for valid_published in components.get("components_published", []):
|
|
@@ -796,6 +800,7 @@ class LearningPackageUnzipper:
|
|
|
796
800
|
self.components_map_by_key[entity_key].publishable_entity.id,
|
|
797
801
|
content_to_replace=content_to_replace,
|
|
798
802
|
force_version_num=valid_published.pop("version_num", None),
|
|
803
|
+
created_by=self.user_id,
|
|
799
804
|
**valid_published
|
|
800
805
|
)
|
|
801
806
|
|
|
@@ -803,7 +808,7 @@ class LearningPackageUnzipper:
|
|
|
803
808
|
"""Save units and published unit versions."""
|
|
804
809
|
for valid_unit in containers.get("unit", []):
|
|
805
810
|
entity_key = valid_unit.get("key")
|
|
806
|
-
unit = units_api.create_unit(learning_package.id, **valid_unit)
|
|
811
|
+
unit = units_api.create_unit(learning_package.id, created_by=self.user_id, **valid_unit)
|
|
807
812
|
self.units_map_by_key[entity_key] = unit
|
|
808
813
|
|
|
809
814
|
for valid_published in containers.get("unit_published", []):
|
|
@@ -816,6 +821,7 @@ class LearningPackageUnzipper:
|
|
|
816
821
|
self.units_map_by_key[entity_key],
|
|
817
822
|
force_version_num=valid_published.pop("version_num", None),
|
|
818
823
|
components=children,
|
|
824
|
+
created_by=self.user_id,
|
|
819
825
|
**valid_published
|
|
820
826
|
)
|
|
821
827
|
|
|
@@ -823,7 +829,9 @@ class LearningPackageUnzipper:
|
|
|
823
829
|
"""Save subsections and published subsection versions."""
|
|
824
830
|
for valid_subsection in containers.get("subsection", []):
|
|
825
831
|
entity_key = valid_subsection.get("key")
|
|
826
|
-
subsection = subsections_api.create_subsection(
|
|
832
|
+
subsection = subsections_api.create_subsection(
|
|
833
|
+
learning_package.id, created_by=self.user_id, **valid_subsection
|
|
834
|
+
)
|
|
827
835
|
self.subsections_map_by_key[entity_key] = subsection
|
|
828
836
|
|
|
829
837
|
for valid_published in containers.get("subsection_published", []):
|
|
@@ -836,6 +844,7 @@ class LearningPackageUnzipper:
|
|
|
836
844
|
self.subsections_map_by_key[entity_key],
|
|
837
845
|
units=children,
|
|
838
846
|
force_version_num=valid_published.pop("version_num", None),
|
|
847
|
+
created_by=self.user_id,
|
|
839
848
|
**valid_published
|
|
840
849
|
)
|
|
841
850
|
|
|
@@ -843,7 +852,7 @@ class LearningPackageUnzipper:
|
|
|
843
852
|
"""Save sections and published section versions."""
|
|
844
853
|
for valid_section in containers.get("section", []):
|
|
845
854
|
entity_key = valid_section.get("key")
|
|
846
|
-
section = sections_api.create_section(learning_package.id, **valid_section)
|
|
855
|
+
section = sections_api.create_section(learning_package.id, created_by=self.user_id, **valid_section)
|
|
847
856
|
self.sections_map_by_key[entity_key] = section
|
|
848
857
|
|
|
849
858
|
for valid_published in containers.get("section_published", []):
|
|
@@ -856,6 +865,7 @@ class LearningPackageUnzipper:
|
|
|
856
865
|
self.sections_map_by_key[entity_key],
|
|
857
866
|
subsections=children,
|
|
858
867
|
force_version_num=valid_published.pop("version_num", None),
|
|
868
|
+
created_by=self.user_id,
|
|
859
869
|
**valid_published
|
|
860
870
|
)
|
|
861
871
|
|
|
@@ -874,6 +884,7 @@ class LearningPackageUnzipper:
|
|
|
874
884
|
# Drafts can diverge from published, so we allow ignoring previous content
|
|
875
885
|
# Use case: published v1 had files A, B; draft v2 only has file A
|
|
876
886
|
ignore_previous_content=True,
|
|
887
|
+
created_by=self.user_id,
|
|
877
888
|
**valid_draft
|
|
878
889
|
)
|
|
879
890
|
|
|
@@ -887,6 +898,7 @@ class LearningPackageUnzipper:
|
|
|
887
898
|
self.units_map_by_key[entity_key],
|
|
888
899
|
components=children,
|
|
889
900
|
force_version_num=valid_draft.pop("version_num", None),
|
|
901
|
+
created_by=self.user_id,
|
|
890
902
|
**valid_draft
|
|
891
903
|
)
|
|
892
904
|
|
|
@@ -900,6 +912,7 @@ class LearningPackageUnzipper:
|
|
|
900
912
|
self.subsections_map_by_key[entity_key],
|
|
901
913
|
units=children,
|
|
902
914
|
force_version_num=valid_draft.pop("version_num", None),
|
|
915
|
+
created_by=self.user_id,
|
|
903
916
|
**valid_draft
|
|
904
917
|
)
|
|
905
918
|
|
|
@@ -913,6 +926,7 @@ class LearningPackageUnzipper:
|
|
|
913
926
|
self.sections_map_by_key[entity_key],
|
|
914
927
|
subsections=children,
|
|
915
928
|
force_version_num=valid_draft.pop("version_num", None),
|
|
929
|
+
created_by=self.user_id,
|
|
916
930
|
**valid_draft
|
|
917
931
|
)
|
|
918
932
|
|
|
@@ -12,7 +12,7 @@ from ..publishing import api as publishing_api
|
|
|
12
12
|
from ..publishing.models import PublishableEntity
|
|
13
13
|
from .models import Collection, CollectionPublishableEntity
|
|
14
14
|
|
|
15
|
-
# The public API that will be re-exported by openedx_learning.apps.
|
|
15
|
+
# The public API that will be re-exported by openedx_learning.apps.openedx_content.api
|
|
16
16
|
# is listed in the __all__ entries below. Internal helper functions that are
|
|
17
17
|
# private to this module should start with an underscore. If a function does not
|
|
18
18
|
# start with an underscore AND it is not in __all__, that function is considered
|
|
@@ -180,7 +180,10 @@ class Collection(models.Model):
|
|
|
180
180
|
),
|
|
181
181
|
]
|
|
182
182
|
indexes = [
|
|
183
|
-
models.Index(
|
|
183
|
+
models.Index(
|
|
184
|
+
fields=["learning_package", "title"],
|
|
185
|
+
name="openedx_content_coll_lp_title",
|
|
186
|
+
),
|
|
184
187
|
]
|
|
185
188
|
|
|
186
189
|
def __repr__(self) -> str:
|
|
@@ -27,7 +27,7 @@ class ComponentVersionInline(admin.TabularInline):
|
|
|
27
27
|
def format_uuid(self, cv_obj):
|
|
28
28
|
return format_html(
|
|
29
29
|
'<a href="{}">{}</a>',
|
|
30
|
-
reverse("admin:
|
|
30
|
+
reverse("admin:openedx_content_componentversion_change", args=(cv_obj.pk,)),
|
|
31
31
|
cv_obj.uuid,
|
|
32
32
|
)
|
|
33
33
|
|
|
@@ -27,7 +27,7 @@ from ..contents import api as contents_api
|
|
|
27
27
|
from ..publishing import api as publishing_api
|
|
28
28
|
from .models import Component, ComponentType, ComponentVersion, ComponentVersionContent
|
|
29
29
|
|
|
30
|
-
# The public API that will be re-exported by openedx_learning.apps.
|
|
30
|
+
# The public API that will be re-exported by openedx_learning.apps.openedx_content.api
|
|
31
31
|
# is listed in the __all__ entries below. Internal helper functions that are
|
|
32
32
|
# private to this module should start with an underscore. If a function does not
|
|
33
33
|
# start with an underscore AND it is not in __all__, that function is considered
|
|
@@ -21,8 +21,9 @@ from typing import ClassVar
|
|
|
21
21
|
|
|
22
22
|
from django.db import models
|
|
23
23
|
|
|
24
|
-
from
|
|
25
|
-
from
|
|
24
|
+
from openedx_learning.lib.fields import case_sensitive_char_field, key_field
|
|
25
|
+
from openedx_learning.lib.managers import WithRelationsManager
|
|
26
|
+
|
|
26
27
|
from ..contents.models import Content
|
|
27
28
|
from ..publishing.models import LearningPackage, PublishableEntityMixin, PublishableEntityVersionMixin
|
|
28
29
|
|
|
@@ -63,6 +64,7 @@ class ComponentType(models.Model):
|
|
|
63
64
|
# the UsageKey.
|
|
64
65
|
name = case_sensitive_char_field(max_length=100, blank=True)
|
|
65
66
|
|
|
67
|
+
# TODO: this needs to go into a class Meta
|
|
66
68
|
constraints = [
|
|
67
69
|
models.UniqueConstraint(
|
|
68
70
|
fields=[
|
|
@@ -12,10 +12,11 @@ from logging import getLogger
|
|
|
12
12
|
from django.core.files.base import ContentFile
|
|
13
13
|
from django.db.transaction import atomic
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from openedx_learning.lib.fields import create_hash_digest
|
|
16
|
+
|
|
16
17
|
from .models import Content, MediaType
|
|
17
18
|
|
|
18
|
-
# The public API that will be re-exported by openedx_learning.apps.
|
|
19
|
+
# The public API that will be re-exported by openedx_learning.apps.openedx_content.api
|
|
19
20
|
# is listed in the __all__ entries below. Internal helper functions that are
|
|
20
21
|
# private to this module should start with an underscore. If a function does not
|
|
21
22
|
# start with an underscore AND it is not in __all__, that function is considered
|
|
@@ -16,8 +16,14 @@ from django.core.validators import MaxValueValidator
|
|
|
16
16
|
from django.db import models
|
|
17
17
|
from django.utils.module_loading import import_string
|
|
18
18
|
|
|
19
|
-
from
|
|
20
|
-
|
|
19
|
+
from openedx_learning.lib.fields import (
|
|
20
|
+
MultiCollationTextField,
|
|
21
|
+
case_insensitive_char_field,
|
|
22
|
+
hash_field,
|
|
23
|
+
manual_date_time_field,
|
|
24
|
+
)
|
|
25
|
+
from openedx_learning.lib.managers import WithRelationsManager
|
|
26
|
+
|
|
21
27
|
from ..publishing.models import LearningPackage
|
|
22
28
|
|
|
23
29
|
logger = getLogger()
|
|
@@ -47,7 +47,7 @@ from .models.publish_log import Published
|
|
|
47
47
|
ContainerModel = TypeVar('ContainerModel', bound=Container)
|
|
48
48
|
ContainerVersionModel = TypeVar('ContainerVersionModel', bound=ContainerVersion)
|
|
49
49
|
|
|
50
|
-
# The public API that will be re-exported by openedx_learning.apps.
|
|
50
|
+
# The public API that will be re-exported by openedx_learning.apps.openedx_content.api
|
|
51
51
|
# is listed in the __all__ entries below. Internal helper functions that are
|
|
52
52
|
# private to this module should start with an underscore. If a function does not
|
|
53
53
|
# start with an underscore AND it is not in __all__, that function is considered
|
|
@@ -7,9 +7,8 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
from django.db.transaction import atomic
|
|
9
9
|
|
|
10
|
-
from openedx_learning.apps.authoring.subsections.models import Subsection, SubsectionVersion
|
|
11
|
-
|
|
12
10
|
from ..publishing import api as publishing_api
|
|
11
|
+
from ..subsections.models import Subsection, SubsectionVersion
|
|
13
12
|
from .models import Section, SectionVersion
|
|
14
13
|
|
|
15
14
|
# 🛑 UNSTABLE: All APIs related to containers are unstable until we've figured
|
|
@@ -7,9 +7,8 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
from django.db.transaction import atomic
|
|
9
9
|
|
|
10
|
-
from openedx_learning.apps.authoring.units.models import Unit, UnitVersion
|
|
11
|
-
|
|
12
10
|
from ..publishing import api as publishing_api
|
|
11
|
+
from ..units.models import Unit, UnitVersion
|
|
13
12
|
from .models import Subsection, SubsectionVersion
|
|
14
13
|
|
|
15
14
|
# 🛑 UNSTABLE: All APIs related to containers are unstable until we've figured
|
|
@@ -7,8 +7,7 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
from django.db.transaction import atomic
|
|
9
9
|
|
|
10
|
-
from
|
|
11
|
-
|
|
10
|
+
from ..components.models import Component, ComponentVersion
|
|
12
11
|
from ..publishing import api as publishing_api
|
|
13
12
|
from .models import Unit, UnitVersion
|
|
14
13
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""
|
|
2
|
+
App Config for our umbrella openedx_content app.
|
|
3
|
+
"""
|
|
4
|
+
from django.apps import AppConfig
|
|
5
|
+
|
|
6
|
+
# pylint: disable=import-outside-toplevel
|
|
7
|
+
#
|
|
8
|
+
# Local imports in AppConfig.ready() are common and expected in Django, since
|
|
9
|
+
# Django needs to run initialization before before we can query for things like
|
|
10
|
+
# models, settings, and app config.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ContentConfig(AppConfig):
|
|
14
|
+
"""
|
|
15
|
+
Initialization for all applets must happen in here.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
name = "openedx_learning.apps.openedx_content"
|
|
19
|
+
verbose_name = "Learning Core > Content"
|
|
20
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
21
|
+
label = "openedx_content"
|
|
22
|
+
|
|
23
|
+
def register_publishable_models(self):
|
|
24
|
+
"""
|
|
25
|
+
Register all Publishable -> Version model pairings in our app.
|
|
26
|
+
"""
|
|
27
|
+
from .api import register_publishable_models
|
|
28
|
+
from .models import (
|
|
29
|
+
Component,
|
|
30
|
+
ComponentVersion,
|
|
31
|
+
Container,
|
|
32
|
+
ContainerVersion,
|
|
33
|
+
Section,
|
|
34
|
+
SectionVersion,
|
|
35
|
+
Subsection,
|
|
36
|
+
SubsectionVersion,
|
|
37
|
+
Unit,
|
|
38
|
+
UnitVersion,
|
|
39
|
+
)
|
|
40
|
+
register_publishable_models(Component, ComponentVersion)
|
|
41
|
+
register_publishable_models(Container, ContainerVersion)
|
|
42
|
+
register_publishable_models(Section, SectionVersion)
|
|
43
|
+
register_publishable_models(Subsection, SubsectionVersion)
|
|
44
|
+
register_publishable_models(Unit, UnitVersion)
|
|
45
|
+
|
|
46
|
+
def ready(self):
|
|
47
|
+
"""
|
|
48
|
+
Currently used to register publishable models.
|
|
49
|
+
|
|
50
|
+
May later be used to register signal handlers as well.
|
|
51
|
+
"""
|
|
52
|
+
self.register_publishable_models()
|
|
@@ -6,7 +6,7 @@ from django.apps import AppConfig
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BackupRestoreConfig(AppConfig):
|
|
9
|
-
name = 'openedx_learning.apps.
|
|
9
|
+
name = 'openedx_learning.apps.openedx_content.backcompat.backup_restore'
|
|
10
10
|
verbose_name = "Learning Core > Authoring > Backup Restore"
|
|
11
11
|
default_auto_field = 'django.db.models.BigAutoField'
|
|
12
12
|
label = "oel_backup_restore"
|
|
@@ -9,7 +9,7 @@ class CollectionsConfig(AppConfig):
|
|
|
9
9
|
Configuration for the Collections Django application.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
name = "openedx_learning.apps.
|
|
12
|
+
name = "openedx_learning.apps.openedx_content.backcompat.collections"
|
|
13
13
|
verbose_name = "Learning Core > Authoring > Collections"
|
|
14
14
|
default_auto_field = "django.db.models.BigAutoField"
|
|
15
15
|
label = "oel_collections"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Generated by Django 5.2.10 on 2026-01-30 00:36
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
from django.db.migrations.operations.special import SeparateDatabaseAndState
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
('oel_collections', '0005_alter_collection_options_alter_collection_enabled'),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
SeparateDatabaseAndState(
|
|
15
|
+
database_operations=[],
|
|
16
|
+
state_operations=[
|
|
17
|
+
migrations.RemoveField(
|
|
18
|
+
model_name='collectionpublishableentity',
|
|
19
|
+
name='collection',
|
|
20
|
+
),
|
|
21
|
+
migrations.RemoveField(
|
|
22
|
+
model_name='collectionpublishableentity',
|
|
23
|
+
name='created_by',
|
|
24
|
+
),
|
|
25
|
+
migrations.RemoveField(
|
|
26
|
+
model_name='collectionpublishableentity',
|
|
27
|
+
name='entity',
|
|
28
|
+
),
|
|
29
|
+
migrations.RemoveField(
|
|
30
|
+
model_name='collection',
|
|
31
|
+
name='entities',
|
|
32
|
+
),
|
|
33
|
+
migrations.AlterModelOptions(
|
|
34
|
+
name='collection',
|
|
35
|
+
options={},
|
|
36
|
+
),
|
|
37
|
+
migrations.RemoveConstraint(
|
|
38
|
+
model_name='collection',
|
|
39
|
+
name='oel_coll_uniq_lp_key',
|
|
40
|
+
),
|
|
41
|
+
migrations.RemoveIndex(
|
|
42
|
+
model_name='collection',
|
|
43
|
+
name='oel_collect_learnin_dfaf89_idx',
|
|
44
|
+
),
|
|
45
|
+
migrations.RemoveField(
|
|
46
|
+
model_name='collection',
|
|
47
|
+
name='created',
|
|
48
|
+
),
|
|
49
|
+
migrations.RemoveField(
|
|
50
|
+
model_name='collection',
|
|
51
|
+
name='created_by',
|
|
52
|
+
),
|
|
53
|
+
migrations.RemoveField(
|
|
54
|
+
model_name='collection',
|
|
55
|
+
name='description',
|
|
56
|
+
),
|
|
57
|
+
migrations.RemoveField(
|
|
58
|
+
model_name='collection',
|
|
59
|
+
name='enabled',
|
|
60
|
+
),
|
|
61
|
+
migrations.RemoveField(
|
|
62
|
+
model_name='collection',
|
|
63
|
+
name='key',
|
|
64
|
+
),
|
|
65
|
+
migrations.RemoveField(
|
|
66
|
+
model_name='collection',
|
|
67
|
+
name='learning_package',
|
|
68
|
+
),
|
|
69
|
+
migrations.RemoveField(
|
|
70
|
+
model_name='collection',
|
|
71
|
+
name='modified',
|
|
72
|
+
),
|
|
73
|
+
migrations.RemoveField(
|
|
74
|
+
model_name='collection',
|
|
75
|
+
name='title',
|
|
76
|
+
),
|
|
77
|
+
migrations.DeleteModel(
|
|
78
|
+
name='CollectionPublishableEntity',
|
|
79
|
+
),
|
|
80
|
+
]
|
|
81
|
+
),
|
|
82
|
+
]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""
|
|
2
|
+
These are stub models necessary to ensure a smooth migration for
|
|
3
|
+
openedx-platform apps that were built to have foreign keys to these models.
|
|
4
|
+
"""
|
|
5
|
+
from django.db import models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Collection(models.Model):
|
|
9
|
+
id = models.AutoField(primary_key=True)
|