openedx-learning 0.10.0__tar.gz → 0.11.1__tar.gz
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-0.10.0/openedx_learning.egg-info → openedx_learning-0.11.1}/PKG-INFO +4 -5
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/__init__.py +1 -1
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/api/authoring.py +6 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/api/authoring_models.py +1 -0
- openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/api.py +80 -0
- openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/apps.py +15 -0
- openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/migrations/0001_initial.py +33 -0
- openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/migrations/0002_remove_collection_name_collection_created_by_and_more.py +53 -0
- openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/models.py +98 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/api.py +2 -2
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/models.py +2 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/api.py +48 -9
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/model_mixins.py +12 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/collations.py +0 -45
- {openedx_learning-0.10.0 → openedx_learning-0.11.1/openedx_learning.egg-info}/PKG-INFO +4 -5
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/SOURCES.txt +7 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/api.py +4 -2
- openedx_learning-0.11.1/openedx_tagging/core/tagging/rest_api/v1/__init__.py +0 -0
- openedx_learning-0.11.1/openedx_tagging/py.typed +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/setup.py +1 -2
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/CHANGELOG.rst +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/LICENSE.txt +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/MANIFEST.in +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/README.rst +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/api/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/components → openedx_learning-0.11.1/openedx_learning/apps/authoring/collections}/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/components → openedx_learning-0.11.1/openedx_learning/apps/authoring/collections}/migrations/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/contents → openedx_learning-0.11.1/openedx_learning/apps/authoring/components}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/admin.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/apps.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/migrations/0001_initial.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/components/migrations/0002_alter_componentversioncontent_key.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/contents → openedx_learning-0.11.1/openedx_learning/apps/authoring/components}/migrations/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/publishing → openedx_learning-0.11.1/openedx_learning/apps/authoring/contents}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/admin.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/api.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/apps.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/migrations/0001_initial.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/apps/authoring/publishing → openedx_learning-0.11.1/openedx_learning/apps/authoring/contents}/migrations/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/models.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/contrib → openedx_learning-0.11.1/openedx_learning/apps/authoring/publishing}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/admin.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/apps.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/migrations/0001_initial.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/migrations/0002_alter_learningpackage_key_and_more.py +0 -0
- {openedx_learning-0.10.0/openedx_learning/lib → openedx_learning-0.11.1/openedx_learning/apps/authoring/publishing/migrations}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/publishing/models.py +0 -0
- {openedx_learning-0.10.0/openedx_tagging/core → openedx_learning-0.11.1/openedx_learning/contrib}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/apps.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/urls.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/views.py +0 -0
- {openedx_learning-0.10.0/openedx_tagging/core/tagging → openedx_learning-0.11.1/openedx_learning/lib}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/admin_utils.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/cache.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/fields.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/managers.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/test_utils.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/lib/validators.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/py.typed +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/dependency_links.txt +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/not-zip-safe +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/requires.txt +2 -2
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/top_level.txt +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_tagging/core/tagging/migrations → openedx_learning-0.11.1/openedx_tagging/core}/__init__.py +0 -0
- {openedx_learning-0.10.0/openedx_tagging/core/tagging/rest_api → openedx_learning-0.11.1/openedx_tagging/core/tagging}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/admin.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/apps.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/data.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/actions.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/api.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/exceptions.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/import_plan.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/parsers.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/tasks.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/template.csv +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/import_export/template.json +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0001_initial.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0001_squashed.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0002_auto_20230718_2026.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0003_auto_20230721_1238.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0004_auto_20230723_2001.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0005_language_taxonomy.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0006_alter_objecttag_unique_together.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0006_auto_20230802_1631.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0007_tag_import_task_log_null_fix.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0008_taxonomy_description_not_null.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0009_alter_objecttag_object_id.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0010_cleanups.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0011_remove_required.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0012_language_taxonomy.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0013_tag_parent_blank.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0014_minor_fixes.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0015_taxonomy_export_id.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0016_object_tag_export_id.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/migrations/0017_alter_tagimporttask_status.py +0 -0
- {openedx_learning-0.10.0/openedx_tagging/core/tagging/rest_api/v1 → openedx_learning-0.11.1/openedx_tagging/core/tagging/migrations}/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/base.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/import_export.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/system_defined.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/utils.py +0 -0
- /openedx_learning-0.10.0/openedx_tagging/py.typed → /openedx_learning-0.11.1/openedx_tagging/core/tagging/rest_api/__init__.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/paginators.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/urls.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/utils.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/permissions.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/serializers.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/urls.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/views.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/views_import.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rules.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/urls.py +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/requirements/base.in +0 -0
- {openedx_learning-0.10.0 → openedx_learning-0.11.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openedx-learning
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: Open edX Learning Core and Tagging.
|
|
5
5
|
Home-page: https://github.com/openedx/openedx-learning
|
|
6
6
|
Author: David Ormsbee
|
|
@@ -14,17 +14,16 @@ Classifier: Intended Audience :: Developers
|
|
|
14
14
|
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.11
|
|
21
20
|
License-File: LICENSE.txt
|
|
22
21
|
Requires-Dist: rules<4.0
|
|
23
|
-
Requires-Dist: Django<5.0
|
|
24
22
|
Requires-Dist: edx-drf-extensions
|
|
25
|
-
Requires-Dist: attrs
|
|
26
23
|
Requires-Dist: celery
|
|
24
|
+
Requires-Dist: attrs
|
|
27
25
|
Requires-Dist: djangorestframework<4.0
|
|
26
|
+
Requires-Dist: Django<5.0
|
|
28
27
|
|
|
29
28
|
Open edX Learning Core (and Tagging)
|
|
30
29
|
====================================
|
|
@@ -9,6 +9,12 @@ 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.authoring.collections.api import *
|
|
12
13
|
from ..apps.authoring.components.api import *
|
|
13
14
|
from ..apps.authoring.contents.api import *
|
|
14
15
|
from ..apps.authoring.publishing.api import *
|
|
16
|
+
|
|
17
|
+
# This was renamed after the authoring API refactoring pushed this and other
|
|
18
|
+
# app APIs into the openedx_learning.api.authoring module. Here I'm aliasing to
|
|
19
|
+
# it's previous name, to make migration a little easier.
|
|
20
|
+
create_next_version = create_next_component_version
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/api/authoring_models.py
RENAMED
|
@@ -7,6 +7,7 @@ consistent.
|
|
|
7
7
|
"""
|
|
8
8
|
# These wildcard imports are okay because these modules declare __all__.
|
|
9
9
|
# pylint: disable=wildcard-import
|
|
10
|
+
from ..apps.authoring.collections.models import *
|
|
10
11
|
from ..apps.authoring.components.models import *
|
|
11
12
|
from ..apps.authoring.contents.models import *
|
|
12
13
|
from ..apps.authoring.publishing.model_mixins import *
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Collections API (warning: UNSTABLE, in progress API)
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from django.db.models import QuerySet
|
|
7
|
+
|
|
8
|
+
from .models import Collection
|
|
9
|
+
|
|
10
|
+
# The public API that will be re-exported by openedx_learning.apps.authoring.api
|
|
11
|
+
# is listed in the __all__ entries below. Internal helper functions that are
|
|
12
|
+
# private to this module should start with an underscore. If a function does not
|
|
13
|
+
# start with an underscore AND it is not in __all__, that function is considered
|
|
14
|
+
# to be callable only by other apps in the authoring package.
|
|
15
|
+
__all__ = [
|
|
16
|
+
"create_collection",
|
|
17
|
+
"get_collection",
|
|
18
|
+
"get_learning_package_collections",
|
|
19
|
+
"update_collection",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def create_collection(
|
|
24
|
+
learning_package_id: int,
|
|
25
|
+
title: str,
|
|
26
|
+
created_by: int | None,
|
|
27
|
+
description: str = "",
|
|
28
|
+
) -> Collection:
|
|
29
|
+
"""
|
|
30
|
+
Create a new Collection
|
|
31
|
+
"""
|
|
32
|
+
collection = Collection.objects.create(
|
|
33
|
+
learning_package_id=learning_package_id,
|
|
34
|
+
title=title,
|
|
35
|
+
created_by_id=created_by,
|
|
36
|
+
description=description,
|
|
37
|
+
)
|
|
38
|
+
return collection
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_collection(collection_id: int) -> Collection:
|
|
42
|
+
"""
|
|
43
|
+
Get a Collection by ID
|
|
44
|
+
"""
|
|
45
|
+
return Collection.objects.get(id=collection_id)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def update_collection(
|
|
49
|
+
collection_id: int,
|
|
50
|
+
title: str | None = None,
|
|
51
|
+
description: str | None = None,
|
|
52
|
+
) -> Collection:
|
|
53
|
+
"""
|
|
54
|
+
Update a Collection
|
|
55
|
+
"""
|
|
56
|
+
collection = Collection.objects.get(id=collection_id)
|
|
57
|
+
|
|
58
|
+
# If no changes were requested, there's nothing to update, so just return
|
|
59
|
+
# the Collection as-is
|
|
60
|
+
if all(field is None for field in [title, description]):
|
|
61
|
+
return collection
|
|
62
|
+
|
|
63
|
+
if title is not None:
|
|
64
|
+
collection.title = title
|
|
65
|
+
if description is not None:
|
|
66
|
+
collection.description = description
|
|
67
|
+
|
|
68
|
+
collection.save()
|
|
69
|
+
return collection
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_learning_package_collections(learning_package_id: int) -> QuerySet[Collection]:
|
|
73
|
+
"""
|
|
74
|
+
Get all collections for a given learning package
|
|
75
|
+
|
|
76
|
+
Only enabled collections are returned
|
|
77
|
+
"""
|
|
78
|
+
return Collection.objects \
|
|
79
|
+
.filter(learning_package_id=learning_package_id, enabled=True) \
|
|
80
|
+
.select_related("learning_package")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Django metadata for the Collections Django application.
|
|
3
|
+
"""
|
|
4
|
+
from django.apps import AppConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class CollectionsConfig(AppConfig):
|
|
8
|
+
"""
|
|
9
|
+
Configuration for the Collections Django application.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
name = "openedx_learning.apps.authoring.collections"
|
|
13
|
+
verbose_name = "Learning Core > Authoring > Collections"
|
|
14
|
+
default_auto_field = "django.db.models.BigAutoField"
|
|
15
|
+
label = "oel_collections"
|
openedx_learning-0.11.1/openedx_learning/apps/authoring/collections/migrations/0001_initial.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Generated by Django 4.2.14 on 2024-08-05 20:42
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
import openedx_learning.lib.fields
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Migration(migrations.Migration):
|
|
10
|
+
|
|
11
|
+
initial = True
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
('oel_publishing', '0002_alter_learningpackage_key_and_more'),
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
operations = [
|
|
18
|
+
migrations.CreateModel(
|
|
19
|
+
name='Collection',
|
|
20
|
+
fields=[
|
|
21
|
+
('id', models.AutoField(primary_key=True, serialize=False)),
|
|
22
|
+
('name', openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, db_index=True, help_text='The name of the collection.', max_length=255)),
|
|
23
|
+
('description', openedx_learning.lib.fields.MultiCollationCharField(blank=True, db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, help_text='Provides extra information for the user about this collection.', max_length=10000)),
|
|
24
|
+
('enabled', models.BooleanField(default=True, help_text='Whether the collection is enabled or not.')),
|
|
25
|
+
('created', models.DateTimeField(auto_now_add=True)),
|
|
26
|
+
('modified', models.DateTimeField(auto_now=True)),
|
|
27
|
+
('learning_package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='oel_publishing.learningpackage')),
|
|
28
|
+
],
|
|
29
|
+
options={
|
|
30
|
+
'verbose_name_plural': 'Collections',
|
|
31
|
+
},
|
|
32
|
+
),
|
|
33
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Generated by Django 4.2.14 on 2024-08-14 14:20
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
import openedx_learning.lib.fields
|
|
8
|
+
import openedx_learning.lib.validators
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Migration(migrations.Migration):
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
15
|
+
('oel_collections', '0001_initial'),
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
operations = [
|
|
19
|
+
migrations.RemoveField(
|
|
20
|
+
model_name='collection',
|
|
21
|
+
name='name',
|
|
22
|
+
),
|
|
23
|
+
migrations.AddField(
|
|
24
|
+
model_name='collection',
|
|
25
|
+
name='created_by',
|
|
26
|
+
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
|
|
27
|
+
),
|
|
28
|
+
migrations.AddField(
|
|
29
|
+
model_name='collection',
|
|
30
|
+
name='title',
|
|
31
|
+
field=openedx_learning.lib.fields.MultiCollationCharField(db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, default='Collection', help_text='The title of the collection.', max_length=500),
|
|
32
|
+
preserve_default=False,
|
|
33
|
+
),
|
|
34
|
+
migrations.AlterField(
|
|
35
|
+
model_name='collection',
|
|
36
|
+
name='created',
|
|
37
|
+
field=models.DateTimeField(auto_now_add=True, validators=[openedx_learning.lib.validators.validate_utc_datetime]),
|
|
38
|
+
),
|
|
39
|
+
migrations.AlterField(
|
|
40
|
+
model_name='collection',
|
|
41
|
+
name='description',
|
|
42
|
+
field=openedx_learning.lib.fields.MultiCollationTextField(blank=True, db_collations={'mysql': 'utf8mb4_unicode_ci', 'sqlite': 'NOCASE'}, default='', help_text='Provides extra information for the user about this collection.', max_length=10000),
|
|
43
|
+
),
|
|
44
|
+
migrations.AlterField(
|
|
45
|
+
model_name='collection',
|
|
46
|
+
name='modified',
|
|
47
|
+
field=models.DateTimeField(auto_now=True, validators=[openedx_learning.lib.validators.validate_utc_datetime]),
|
|
48
|
+
),
|
|
49
|
+
migrations.AddIndex(
|
|
50
|
+
model_name='collection',
|
|
51
|
+
index=models.Index(fields=['learning_package', 'title'], name='oel_collect_learnin_dfaf89_idx'),
|
|
52
|
+
),
|
|
53
|
+
]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core models for Collections
|
|
3
|
+
"""
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from django.conf import settings
|
|
7
|
+
from django.db import models
|
|
8
|
+
from django.utils.translation import gettext_lazy as _
|
|
9
|
+
|
|
10
|
+
from ....lib.fields import MultiCollationTextField, case_insensitive_char_field
|
|
11
|
+
from ....lib.validators import validate_utc_datetime
|
|
12
|
+
from ..publishing.models import LearningPackage
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"Collection",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Collection(models.Model):
|
|
20
|
+
"""
|
|
21
|
+
Represents a collection of library components
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
id = models.AutoField(primary_key=True)
|
|
25
|
+
|
|
26
|
+
# Each collection belongs to a learning package
|
|
27
|
+
learning_package = models.ForeignKey(LearningPackage, on_delete=models.CASCADE)
|
|
28
|
+
|
|
29
|
+
title = case_insensitive_char_field(
|
|
30
|
+
null=False,
|
|
31
|
+
blank=False,
|
|
32
|
+
max_length=500,
|
|
33
|
+
help_text=_(
|
|
34
|
+
"The title of the collection."
|
|
35
|
+
),
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
description = MultiCollationTextField(
|
|
39
|
+
blank=True,
|
|
40
|
+
null=False,
|
|
41
|
+
default="",
|
|
42
|
+
max_length=10_000,
|
|
43
|
+
help_text=_(
|
|
44
|
+
"Provides extra information for the user about this collection."
|
|
45
|
+
),
|
|
46
|
+
db_collations={
|
|
47
|
+
"sqlite": "NOCASE",
|
|
48
|
+
"mysql": "utf8mb4_unicode_ci",
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# We don't have api functions to handle the enabled field. This is a placeholder for future use and
|
|
53
|
+
# a way to "soft delete" collections.
|
|
54
|
+
enabled = models.BooleanField(
|
|
55
|
+
default=True,
|
|
56
|
+
help_text=_(
|
|
57
|
+
"Whether the collection is enabled or not."
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
created_by = models.ForeignKey(
|
|
62
|
+
settings.AUTH_USER_MODEL,
|
|
63
|
+
on_delete=models.SET_NULL,
|
|
64
|
+
null=True,
|
|
65
|
+
blank=True,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
created = models.DateTimeField(
|
|
69
|
+
auto_now_add=True,
|
|
70
|
+
validators=[
|
|
71
|
+
validate_utc_datetime,
|
|
72
|
+
],
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
modified = models.DateTimeField(
|
|
76
|
+
auto_now=True,
|
|
77
|
+
validators=[
|
|
78
|
+
validate_utc_datetime,
|
|
79
|
+
],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
class Meta:
|
|
83
|
+
verbose_name_plural = "Collections"
|
|
84
|
+
indexes = [
|
|
85
|
+
models.Index(fields=["learning_package", "title"]),
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
def __repr__(self) -> str:
|
|
89
|
+
"""
|
|
90
|
+
Developer-facing representation of a Collection.
|
|
91
|
+
"""
|
|
92
|
+
return str(self)
|
|
93
|
+
|
|
94
|
+
def __str__(self) -> str:
|
|
95
|
+
"""
|
|
96
|
+
User-facing string representation of a Collection.
|
|
97
|
+
"""
|
|
98
|
+
return f"<{self.__class__.__name__}> ({self.id}:{self.title})"
|
|
@@ -30,7 +30,7 @@ __all__ = [
|
|
|
30
30
|
"get_or_create_component_type",
|
|
31
31
|
"create_component",
|
|
32
32
|
"create_component_version",
|
|
33
|
-
"
|
|
33
|
+
"create_next_component_version",
|
|
34
34
|
"create_component_and_version",
|
|
35
35
|
"get_component",
|
|
36
36
|
"get_component_by_key",
|
|
@@ -109,7 +109,7 @@ def create_component_version(
|
|
|
109
109
|
return component_version
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
def
|
|
112
|
+
def create_next_component_version(
|
|
113
113
|
component_pk: int,
|
|
114
114
|
/,
|
|
115
115
|
title: str,
|
|
@@ -134,6 +134,8 @@ class Component(PublishableEntityMixin): # type: ignore[django-manager-missing]
|
|
|
134
134
|
'publishable_entity__draft__version__componentversion',
|
|
135
135
|
'publishable_entity__published__version',
|
|
136
136
|
'publishable_entity__published__version__componentversion',
|
|
137
|
+
'publishable_entity__published__publish_log_record',
|
|
138
|
+
'publishable_entity__published__publish_log_record__publish_log',
|
|
137
139
|
)
|
|
138
140
|
|
|
139
141
|
# This foreign key is technically redundant because we're already locked to
|
|
@@ -9,7 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
from datetime import datetime, timezone
|
|
10
10
|
|
|
11
11
|
from django.core.exceptions import ObjectDoesNotExist
|
|
12
|
-
from django.db.models import F, QuerySet
|
|
12
|
+
from django.db.models import F, Q, QuerySet
|
|
13
13
|
from django.db.transaction import atomic
|
|
14
14
|
|
|
15
15
|
from .model_mixins import PublishableContentModelRegistry, PublishableEntityMixin, PublishableEntityVersionMixin
|
|
@@ -216,10 +216,36 @@ def get_all_drafts(learning_package_id: int, /) -> QuerySet[Draft]:
|
|
|
216
216
|
)
|
|
217
217
|
|
|
218
218
|
|
|
219
|
-
def get_entities_with_unpublished_changes(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
def get_entities_with_unpublished_changes(
|
|
220
|
+
learning_package_id: int,
|
|
221
|
+
/,
|
|
222
|
+
include_deleted_drafts: bool = False
|
|
223
|
+
) -> QuerySet[PublishableEntity]:
|
|
224
|
+
"""
|
|
225
|
+
Fetch entities that have unpublished changes.
|
|
226
|
+
|
|
227
|
+
By default, this excludes soft-deleted drafts but can be included using include_deleted_drafts option.
|
|
228
|
+
"""
|
|
229
|
+
entities_qs = (
|
|
230
|
+
PublishableEntity.objects
|
|
231
|
+
.filter(learning_package_id=learning_package_id)
|
|
232
|
+
.exclude(draft__version=F('published__version'))
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
if include_deleted_drafts:
|
|
236
|
+
# This means that we should also return PublishableEntities where the draft
|
|
237
|
+
# has been soft-deleted, but that deletion has not been published yet. Just
|
|
238
|
+
# excluding records where the Draft and Published versions don't match won't
|
|
239
|
+
# be enough here, because that will return soft-deletes that have already
|
|
240
|
+
# been published (since NULL != NULL in SQL).
|
|
241
|
+
#
|
|
242
|
+
# So we explicitly exclude already-published soft-deletes:
|
|
243
|
+
return entities_qs.exclude(
|
|
244
|
+
Q(draft__version__isnull=True) & Q(published__version__isnull=True)
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
# Simple case: exclude all entities that have been soft-deleted.
|
|
248
|
+
return entities_qs.exclude(draft__version__isnull=True)
|
|
223
249
|
|
|
224
250
|
|
|
225
251
|
def get_entities_with_unpublished_deletes(learning_package_id: int, /) -> QuerySet[PublishableEntity]:
|
|
@@ -245,10 +271,23 @@ def publish_all_drafts(
|
|
|
245
271
|
"""
|
|
246
272
|
Publish everything that is a Draft and is not already published.
|
|
247
273
|
"""
|
|
248
|
-
draft_qset =
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
274
|
+
draft_qset = (
|
|
275
|
+
Draft.objects.select_related("entity__published")
|
|
276
|
+
.filter(entity__learning_package_id=learning_package_id)
|
|
277
|
+
|
|
278
|
+
# Exclude entities where the Published version already matches the
|
|
279
|
+
# Draft version.
|
|
280
|
+
.exclude(entity__published__version_id=F("version_id"))
|
|
281
|
+
|
|
282
|
+
# Account for soft-deletes:
|
|
283
|
+
# NULL != NULL in SQL, so simply excluding entities where the Draft
|
|
284
|
+
# and Published versions match will not catch the case where a
|
|
285
|
+
# soft-delete has been published (i.e. both the Draft and Published
|
|
286
|
+
# versions are NULL). We need to explicitly check for that case
|
|
287
|
+
# instead, or else we will re-publish the same soft-deletes over
|
|
288
|
+
# and over again.
|
|
289
|
+
.exclude(Q(version__isnull=True) & Q(entity__published__version__isnull=True))
|
|
290
|
+
)
|
|
252
291
|
return publish_from_drafts(
|
|
253
292
|
learning_package_id, draft_qset, message, published_at, published_by
|
|
254
293
|
)
|
|
@@ -243,6 +243,18 @@ class PublishableEntityMixin(models.Model):
|
|
|
243
243
|
|
|
244
244
|
return draft_version_id != published_version_id
|
|
245
245
|
|
|
246
|
+
@property
|
|
247
|
+
def last_publish_log(self):
|
|
248
|
+
"""
|
|
249
|
+
Return the most recent PublishLog for this component.
|
|
250
|
+
|
|
251
|
+
Return None if the component is not published.
|
|
252
|
+
"""
|
|
253
|
+
pub_entity = self.content_obj.publishable_entity
|
|
254
|
+
if hasattr(pub_entity, 'published'):
|
|
255
|
+
return pub_entity.published.publish_log_record.publish_log
|
|
256
|
+
return None
|
|
257
|
+
|
|
246
258
|
@property
|
|
247
259
|
def versions(self):
|
|
248
260
|
"""
|
|
@@ -36,48 +36,6 @@ class MultiCollationMixin:
|
|
|
36
36
|
super().__init__(*args, **kwargs)
|
|
37
37
|
self.db_collations = db_collations or {}
|
|
38
38
|
|
|
39
|
-
# This is part of a hack to get this to work for Django < 4.1. Please
|
|
40
|
-
# see comments in the db_collation method for details.
|
|
41
|
-
self._vendor = None
|
|
42
|
-
|
|
43
|
-
@property
|
|
44
|
-
def db_collation(self):
|
|
45
|
-
"""
|
|
46
|
-
Return the db_collation, understanding that it varies by vendor.
|
|
47
|
-
|
|
48
|
-
This method is a hack for Django 3.2 compatibility and should be removed
|
|
49
|
-
after we move to 4.2.
|
|
50
|
-
|
|
51
|
-
Description of why this is hacky:
|
|
52
|
-
|
|
53
|
-
In Django 4.2, the schema builder pulls the collation settings from the
|
|
54
|
-
field using the value returned from the ``db_parameters`` method, and
|
|
55
|
-
this does what we want it to do. In Django 3.2, field.db_parameters is
|
|
56
|
-
called, but any collation value sent back is ignored and the code grabs
|
|
57
|
-
the value of db_collation directly from the field:
|
|
58
|
-
|
|
59
|
-
https://github.com/django/django/blob/stable/3.2.x/django/db/backends/base/schema.py#L214-L224
|
|
60
|
-
|
|
61
|
-
But this call to get the ``field.db_collation`` attribute happens almost
|
|
62
|
-
immediately after the ``field.db_parameters`` method call. So our
|
|
63
|
-
fragile hack is to set ``self._vendor`` in the ``db_parameters`` method,
|
|
64
|
-
using the value we get from the connection that is passed in there. We
|
|
65
|
-
can then use ``self._vendor`` to return the right value when Django
|
|
66
|
-
calls ``field.db_collation`` (which is this property method).
|
|
67
|
-
|
|
68
|
-
This method, the corresponding setter, and all references to
|
|
69
|
-
``self._vendor`` should be removed after we've cut over to Django 4.2.
|
|
70
|
-
"""
|
|
71
|
-
return self.db_collations.get(self._vendor)
|
|
72
|
-
|
|
73
|
-
@db_collation.setter
|
|
74
|
-
def db_collation(self, value):
|
|
75
|
-
"""
|
|
76
|
-
Don't allow db_collation to be set manually (just ignore).
|
|
77
|
-
|
|
78
|
-
This can be removed when we move to Django 4.2.
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
39
|
def db_parameters(self, connection):
|
|
82
40
|
"""
|
|
83
41
|
Return database parameters for this field. This adds collation info.
|
|
@@ -88,9 +46,6 @@ class MultiCollationMixin:
|
|
|
88
46
|
"""
|
|
89
47
|
db_params = models.Field.db_parameters(self, connection)
|
|
90
48
|
|
|
91
|
-
# Remove once we no longer need to support Django < 4.1
|
|
92
|
-
self._vendor = connection.vendor
|
|
93
|
-
|
|
94
49
|
# Now determine collation based on DB vendor (e.g. 'sqlite', 'mysql')
|
|
95
50
|
if connection.vendor in self.db_collations:
|
|
96
51
|
db_params["collation"] = self.db_collations[connection.vendor]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: openedx-learning
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: Open edX Learning Core and Tagging.
|
|
5
5
|
Home-page: https://github.com/openedx/openedx-learning
|
|
6
6
|
Author: David Ormsbee
|
|
@@ -14,17 +14,16 @@ Classifier: Intended Audience :: Developers
|
|
|
14
14
|
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.11
|
|
21
20
|
License-File: LICENSE.txt
|
|
22
21
|
Requires-Dist: rules<4.0
|
|
23
|
-
Requires-Dist: Django<5.0
|
|
24
22
|
Requires-Dist: edx-drf-extensions
|
|
25
|
-
Requires-Dist: attrs
|
|
26
23
|
Requires-Dist: celery
|
|
24
|
+
Requires-Dist: attrs
|
|
27
25
|
Requires-Dist: djangorestframework<4.0
|
|
26
|
+
Requires-Dist: Django<5.0
|
|
28
27
|
|
|
29
28
|
Open edX Learning Core (and Tagging)
|
|
30
29
|
====================================
|
|
@@ -17,6 +17,13 @@ openedx_learning/api/authoring.py
|
|
|
17
17
|
openedx_learning/api/authoring_models.py
|
|
18
18
|
openedx_learning/apps/__init__.py
|
|
19
19
|
openedx_learning/apps/authoring/__init__.py
|
|
20
|
+
openedx_learning/apps/authoring/collections/__init__.py
|
|
21
|
+
openedx_learning/apps/authoring/collections/api.py
|
|
22
|
+
openedx_learning/apps/authoring/collections/apps.py
|
|
23
|
+
openedx_learning/apps/authoring/collections/models.py
|
|
24
|
+
openedx_learning/apps/authoring/collections/migrations/0001_initial.py
|
|
25
|
+
openedx_learning/apps/authoring/collections/migrations/0002_remove_collection_name_collection_created_by_and_more.py
|
|
26
|
+
openedx_learning/apps/authoring/collections/migrations/__init__.py
|
|
20
27
|
openedx_learning/apps/authoring/components/__init__.py
|
|
21
28
|
openedx_learning/apps/authoring/components/admin.py
|
|
22
29
|
openedx_learning/apps/authoring/components/api.py
|
|
@@ -190,8 +190,10 @@ def get_object_tags(
|
|
|
190
190
|
.exclude(taxonomy__enabled=False) # Exclude if the whole taxonomy is disabled
|
|
191
191
|
)
|
|
192
192
|
if not include_deleted:
|
|
193
|
-
|
|
194
|
-
base_qs = base_qs.exclude(
|
|
193
|
+
# Exclude if the whole taxonomy was deleted
|
|
194
|
+
base_qs = base_qs.exclude(taxonomy_id=None) # type: ignore
|
|
195
|
+
# Exclude if just the tag is deleted
|
|
196
|
+
base_qs = base_qs.exclude(tag_id=None, taxonomy__allow_free_text=False) # type: ignore
|
|
195
197
|
tags = (
|
|
196
198
|
base_qs
|
|
197
199
|
# Preload related objects, including data for the "get_lineage" method on ObjectTag/Tag:
|
|
File without changes
|
|
File without changes
|
|
@@ -78,7 +78,7 @@ setup(
|
|
|
78
78
|
),
|
|
79
79
|
include_package_data=True,
|
|
80
80
|
install_requires=load_requirements('requirements/base.in'),
|
|
81
|
-
python_requires=">=3.
|
|
81
|
+
python_requires=">=3.11",
|
|
82
82
|
license="AGPL 3.0",
|
|
83
83
|
zip_safe=False,
|
|
84
84
|
keywords='Python edx',
|
|
@@ -90,7 +90,6 @@ setup(
|
|
|
90
90
|
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
|
|
91
91
|
'Natural Language :: English',
|
|
92
92
|
'Programming Language :: Python :: 3',
|
|
93
|
-
'Programming Language :: Python :: 3.8',
|
|
94
93
|
'Programming Language :: Python :: 3.11',
|
|
95
94
|
'Programming Language :: Python :: 3.12',
|
|
96
95
|
],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/api.py
RENAMED
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/apps/authoring/contents/apps.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/apps.py
RENAMED
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/urls.py
RENAMED
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning/contrib/media_server/views.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_learning.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/__init__.py
RENAMED
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/models/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/urls.py
RENAMED
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.10.0 → openedx_learning-0.11.1}/openedx_tagging/core/tagging/rest_api/v1/urls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|