openedx-learning 0.27.0__tar.gz → 0.27.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.27.0/openedx_learning.egg-info → openedx_learning-0.27.1}/PKG-INFO +5 -5
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/__init__.py +1 -1
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/api/authoring.py +1 -0
- openedx_learning-0.27.1/openedx_learning/apps/authoring/backup_restore/api.py +15 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/management/commands/lp_dump.py +0 -1
- openedx_learning-0.27.1/openedx_learning/apps/authoring/backup_restore/toml.py +75 -0
- openedx_learning-0.27.1/openedx_learning/apps/authoring/backup_restore/zipper.py +53 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/apps.py +2 -2
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/api.py +41 -8
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/apps.py +2 -2
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/publishable_entity.py +7 -3
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/api.py +6 -1
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/apps.py +2 -2
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/api.py +6 -1
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/apps.py +2 -2
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/api.py +6 -1
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/apps.py +2 -2
- {openedx_learning-0.27.0 → openedx_learning-0.27.1/openedx_learning.egg-info}/PKG-INFO +5 -5
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning.egg-info/SOURCES.txt +1 -0
- openedx_learning-0.27.0/openedx_learning/apps/authoring/backup_restore/api.py +0 -25
- openedx_learning-0.27.0/openedx_learning/apps/authoring/backup_restore/toml.py +0 -72
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/CHANGELOG.rst +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/LICENSE.txt +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/MANIFEST.in +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/README.rst +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/api/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/api/authoring_models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/apps.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/management/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/management/commands/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/backup_restore/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/api.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/apps.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/0002_remove_collection_name_collection_created_by_and_more.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/0003_collection_entities.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/0004_collection_key.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/0005_alter_collection_options_alter_collection_enabled.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/collections/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/api.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/management/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/management/commands/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/management/commands/add_assets_to_component.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/migrations/0002_alter_componentversioncontent_key.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/migrations/0003_remove_componentversioncontent_learner_downloadable.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/components/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/api.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/apps.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/contents/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/contextmanagers.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0002_alter_learningpackage_key_and_more.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0003_containers.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0004_publishableentity_can_stand_alone.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0005_alter_entitylistrow_options.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0006_draftchangelog.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0007_bootstrap_draftchangelog.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/0008_alter_draftchangelogrecord_options_and_more.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/container.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/draft_log.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/entity_list.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/learning_package.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/publishing/models/publish_log.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/subsections/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/models.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/contrib/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/contrib/media_server/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/contrib/media_server/apps.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/contrib/media_server/urls.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/contrib/media_server/views.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/admin_utils.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/cache.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/collations.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/fields.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/managers.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/test_utils.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/lib/validators.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/py.typed +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning.egg-info/dependency_links.txt +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning.egg-info/not-zip-safe +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning.egg-info/requires.txt +4 -4
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning.egg-info/top_level.txt +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/admin.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/api.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/apps.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/data.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/actions.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/api.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/exceptions.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/import_plan.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/parsers.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/tasks.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/template.csv +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/import_export/template.json +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0001_initial.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0001_squashed.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0002_auto_20230718_2026.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0003_auto_20230721_1238.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0004_auto_20230723_2001.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0005_language_taxonomy.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0006_alter_objecttag_unique_together.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0006_auto_20230802_1631.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0007_tag_import_task_log_null_fix.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0008_taxonomy_description_not_null.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0009_alter_objecttag_object_id.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0010_cleanups.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0011_remove_required.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0012_language_taxonomy.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0013_tag_parent_blank.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0014_minor_fixes.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0015_taxonomy_export_id.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0016_object_tag_export_id.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0017_alter_tagimporttask_status.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/0018_objecttag_is_copied.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/migrations/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/models/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/models/base.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/models/import_export.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/models/system_defined.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/models/utils.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/paginators.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/urls.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/utils.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/__init__.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/permissions.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/serializers.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/urls.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/views.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rest_api/v1/views_import.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/rules.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/core/tagging/urls.py +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_tagging/py.typed +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/requirements/base.in +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/setup.cfg +0 -0
- {openedx_learning-0.27.0 → openedx_learning-0.27.1}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openedx-learning
|
|
3
|
-
Version: 0.27.
|
|
3
|
+
Version: 0.27.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
|
|
@@ -19,13 +19,13 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
License-File: LICENSE.txt
|
|
22
|
-
Requires-Dist: Django
|
|
23
|
-
Requires-Dist: rules<4.0
|
|
24
|
-
Requires-Dist: celery
|
|
25
22
|
Requires-Dist: djangorestframework<4.0
|
|
26
|
-
Requires-Dist: attrs
|
|
27
23
|
Requires-Dist: tomlkit
|
|
24
|
+
Requires-Dist: celery
|
|
25
|
+
Requires-Dist: Django
|
|
26
|
+
Requires-Dist: attrs
|
|
28
27
|
Requires-Dist: edx-drf-extensions
|
|
28
|
+
Requires-Dist: rules<4.0
|
|
29
29
|
Dynamic: author
|
|
30
30
|
Dynamic: author-email
|
|
31
31
|
Dynamic: classifier
|
|
@@ -9,6 +9,7 @@ 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.backup_restore.api import *
|
|
12
13
|
from ..apps.authoring.collections.api import *
|
|
13
14
|
from ..apps.authoring.components.api import *
|
|
14
15
|
from ..apps.authoring.contents.api import *
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Backup Restore API
|
|
3
|
+
"""
|
|
4
|
+
from openedx_learning.apps.authoring.backup_restore.zipper import LearningPackageZipper
|
|
5
|
+
from openedx_learning.apps.authoring.publishing.api import get_learning_package_by_key
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def create_zip_file(lp_key: str, path: str) -> None:
|
|
9
|
+
"""
|
|
10
|
+
Creates a zip file with a toml file so far (WIP)
|
|
11
|
+
|
|
12
|
+
Can throw a NotFoundError at get_learning_package_by_key
|
|
13
|
+
"""
|
|
14
|
+
learning_package = get_learning_package_by_key(lp_key)
|
|
15
|
+
LearningPackageZipper(learning_package).create_zip(path)
|
|
@@ -33,7 +33,6 @@ class Command(BaseCommand):
|
|
|
33
33
|
self.stdout.write(self.style.SUCCESS(message))
|
|
34
34
|
except LearningPackage.DoesNotExist as exc:
|
|
35
35
|
message = f"Learning package with key {lp_key} not found"
|
|
36
|
-
logger.exception(message)
|
|
37
36
|
raise CommandError(message) from exc
|
|
38
37
|
except Exception as e:
|
|
39
38
|
message = f"Failed to export learning package '{lp_key}': {e}"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TOML serialization for learning packages and publishable entities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
import tomlkit
|
|
8
|
+
|
|
9
|
+
from openedx_learning.apps.authoring.publishing.models import PublishableEntity, PublishableEntityVersion
|
|
10
|
+
from openedx_learning.apps.authoring.publishing.models.learning_package import LearningPackage
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def toml_learning_package(learning_package: LearningPackage) -> str:
|
|
14
|
+
"""Create a TOML representation of the learning package."""
|
|
15
|
+
doc = tomlkit.document()
|
|
16
|
+
doc.add(tomlkit.comment(f"Datetime of the export: {datetime.now()}"))
|
|
17
|
+
section = tomlkit.table()
|
|
18
|
+
section.add("title", learning_package.title)
|
|
19
|
+
section.add("key", learning_package.key)
|
|
20
|
+
section.add("description", learning_package.description)
|
|
21
|
+
section.add("created", learning_package.created)
|
|
22
|
+
section.add("updated", learning_package.updated)
|
|
23
|
+
doc.add("learning_package", section)
|
|
24
|
+
return tomlkit.dumps(doc)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def toml_publishable_entity(entity: PublishableEntity) -> str:
|
|
28
|
+
"""Create a TOML representation of a publishable entity."""
|
|
29
|
+
|
|
30
|
+
current_draft_version = getattr(entity, "draft", None)
|
|
31
|
+
current_published_version = getattr(entity, "published", None)
|
|
32
|
+
|
|
33
|
+
doc = tomlkit.document()
|
|
34
|
+
entity_table = tomlkit.table()
|
|
35
|
+
entity_table.add("uuid", str(entity.uuid))
|
|
36
|
+
entity_table.add("can_stand_alone", entity.can_stand_alone)
|
|
37
|
+
|
|
38
|
+
if current_draft_version:
|
|
39
|
+
draft_table = tomlkit.table()
|
|
40
|
+
draft_table.add("version_num", current_draft_version.version.version_num)
|
|
41
|
+
entity_table.add("draft", draft_table)
|
|
42
|
+
|
|
43
|
+
published_table = tomlkit.table()
|
|
44
|
+
if current_published_version:
|
|
45
|
+
published_table.add("version_num", current_published_version.version.version_num)
|
|
46
|
+
else:
|
|
47
|
+
published_table.add(tomlkit.comment("unpublished: no published_version_num"))
|
|
48
|
+
entity_table.add("published", published_table)
|
|
49
|
+
|
|
50
|
+
doc.add("entity", entity_table)
|
|
51
|
+
doc.add(tomlkit.nl())
|
|
52
|
+
doc.add(tomlkit.comment("### Versions"))
|
|
53
|
+
|
|
54
|
+
for entity_version in entity.versions.all():
|
|
55
|
+
version = tomlkit.aot()
|
|
56
|
+
version_table = toml_publishable_entity_version(entity_version)
|
|
57
|
+
version.append(version_table)
|
|
58
|
+
doc.add("version", version)
|
|
59
|
+
|
|
60
|
+
return tomlkit.dumps(doc)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def toml_publishable_entity_version(version: PublishableEntityVersion) -> tomlkit.items.Table:
|
|
64
|
+
"""Create a TOML representation of a publishable entity version."""
|
|
65
|
+
version_table = tomlkit.table()
|
|
66
|
+
version_table.add("title", version.title)
|
|
67
|
+
version_table.add("uuid", str(version.uuid))
|
|
68
|
+
version_table.add("version_num", version.version_num)
|
|
69
|
+
container_table = tomlkit.table()
|
|
70
|
+
container_table.add("children", [])
|
|
71
|
+
unit_table = tomlkit.table()
|
|
72
|
+
unit_table.add("graded", True)
|
|
73
|
+
container_table.add("unit", unit_table)
|
|
74
|
+
version_table.add("container", container_table)
|
|
75
|
+
return version_table # For use in AoT
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides functionality to create a zip file containing the learning package data,
|
|
3
|
+
including a TOML representation of the learning package and its entities.
|
|
4
|
+
"""
|
|
5
|
+
import zipfile
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from openedx_learning.apps.authoring.backup_restore.toml import toml_learning_package, toml_publishable_entity
|
|
9
|
+
from openedx_learning.apps.authoring.publishing import api as publishing_api
|
|
10
|
+
from openedx_learning.apps.authoring.publishing.models.learning_package import LearningPackage
|
|
11
|
+
|
|
12
|
+
TOML_PACKAGE_NAME = "package.toml"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class LearningPackageZipper:
|
|
16
|
+
"""
|
|
17
|
+
A class to handle the zipping of learning content for backup and restore.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, learning_package: LearningPackage):
|
|
21
|
+
self.learning_package = learning_package
|
|
22
|
+
|
|
23
|
+
def create_zip(self, path: str) -> None:
|
|
24
|
+
"""
|
|
25
|
+
Creates a zip file containing the learning package data.
|
|
26
|
+
Args:
|
|
27
|
+
path (str): The path where the zip file will be created.
|
|
28
|
+
Raises:
|
|
29
|
+
Exception: If the learning package cannot be found or if the zip creation fails.
|
|
30
|
+
"""
|
|
31
|
+
package_toml_content: str = toml_learning_package(self.learning_package)
|
|
32
|
+
|
|
33
|
+
with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as zipf:
|
|
34
|
+
# Add the package.toml string
|
|
35
|
+
zipf.writestr(TOML_PACKAGE_NAME, package_toml_content)
|
|
36
|
+
|
|
37
|
+
# Add the entities directory
|
|
38
|
+
entities_folder = Path("entities")
|
|
39
|
+
zip_info = zipfile.ZipInfo(str(entities_folder) + "/") # Ensure trailing slash
|
|
40
|
+
zipf.writestr(zip_info, "") # Add explicit empty directory entry
|
|
41
|
+
|
|
42
|
+
# Add the collections directory
|
|
43
|
+
collections_folder = Path("collections")
|
|
44
|
+
collections_info = zipfile.ZipInfo(str(collections_folder) + "/") # Ensure trailing slash
|
|
45
|
+
zipf.writestr(collections_info, "") # Add explicit empty directory
|
|
46
|
+
|
|
47
|
+
# Add each entity's TOML file
|
|
48
|
+
for entity in publishing_api.get_entities(self.learning_package.pk):
|
|
49
|
+
# Create a TOML representation of the entity
|
|
50
|
+
entity_toml_content: str = toml_publishable_entity(entity)
|
|
51
|
+
entity_toml_filename = f"{entity.key}.toml"
|
|
52
|
+
entity_toml_path = entities_folder / entity_toml_filename
|
|
53
|
+
zipf.writestr(str(entity_toml_path), entity_toml_content)
|
|
@@ -18,7 +18,7 @@ class ComponentsConfig(AppConfig):
|
|
|
18
18
|
"""
|
|
19
19
|
Register Component and ComponentVersion.
|
|
20
20
|
"""
|
|
21
|
-
from ..publishing.api import
|
|
21
|
+
from ..publishing.api import register_publishable_models # pylint: disable=import-outside-toplevel
|
|
22
22
|
from .models import Component, ComponentVersion # pylint: disable=import-outside-toplevel
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
register_publishable_models(Component, ComponentVersion)
|
|
@@ -60,6 +60,7 @@ __all__ = [
|
|
|
60
60
|
"get_publishable_entity_by_key",
|
|
61
61
|
"get_last_publish",
|
|
62
62
|
"get_all_drafts",
|
|
63
|
+
"get_entities",
|
|
63
64
|
"get_entities_with_unpublished_changes",
|
|
64
65
|
"get_entities_with_unpublished_deletes",
|
|
65
66
|
"publish_all_drafts",
|
|
@@ -69,7 +70,7 @@ __all__ = [
|
|
|
69
70
|
"set_draft_version",
|
|
70
71
|
"soft_delete_draft",
|
|
71
72
|
"reset_drafts_to_published",
|
|
72
|
-
"
|
|
73
|
+
"register_publishable_models",
|
|
73
74
|
"filter_publishable_entities",
|
|
74
75
|
# 🛑 UNSTABLE: All APIs related to containers are unstable until we've figured
|
|
75
76
|
# out our approach to dynamic content (randomized, A/B tests, etc.)
|
|
@@ -261,6 +262,13 @@ def get_all_drafts(learning_package_id: int, /) -> QuerySet[Draft]:
|
|
|
261
262
|
)
|
|
262
263
|
|
|
263
264
|
|
|
265
|
+
def get_entities(learning_package_id: int, /) -> QuerySet[PublishableEntity]:
|
|
266
|
+
"""
|
|
267
|
+
Get all entities in a learning package.
|
|
268
|
+
"""
|
|
269
|
+
return PublishableEntity.objects.filter(learning_package_id=learning_package_id)
|
|
270
|
+
|
|
271
|
+
|
|
264
272
|
def get_entities_with_unpublished_changes(
|
|
265
273
|
learning_package_id: int,
|
|
266
274
|
/,
|
|
@@ -789,7 +797,7 @@ def reset_drafts_to_published(
|
|
|
789
797
|
set_draft_version(draft, published_version_id)
|
|
790
798
|
|
|
791
799
|
|
|
792
|
-
def
|
|
800
|
+
def register_publishable_models(
|
|
793
801
|
content_model_cls: type[PublishableEntityMixin],
|
|
794
802
|
content_version_model_cls: type[PublishableEntityVersionMixin],
|
|
795
803
|
) -> PublishableContentModelRegistry:
|
|
@@ -805,10 +813,10 @@ def register_content_models(
|
|
|
805
813
|
method. For example, in the components app, this looks like:
|
|
806
814
|
|
|
807
815
|
def ready(self):
|
|
808
|
-
from ..publishing.api import
|
|
816
|
+
from ..publishing.api import register_publishable_models
|
|
809
817
|
from .models import Component, ComponentVersion
|
|
810
818
|
|
|
811
|
-
|
|
819
|
+
register_publishable_models(Component, ComponentVersion)
|
|
812
820
|
|
|
813
821
|
There may be a more clever way to introspect this information from the model
|
|
814
822
|
metadata, but this is simple and explicit.
|
|
@@ -1275,6 +1283,7 @@ def get_entities_in_container(
|
|
|
1275
1283
|
container: Container,
|
|
1276
1284
|
*,
|
|
1277
1285
|
published: bool,
|
|
1286
|
+
select_related_version: str | None = None,
|
|
1278
1287
|
) -> list[ContainerEntityListEntry]:
|
|
1279
1288
|
"""
|
|
1280
1289
|
[ 🛑 UNSTABLE ]
|
|
@@ -1285,14 +1294,35 @@ def get_entities_in_container(
|
|
|
1285
1294
|
container: The Container, e.g. returned by `get_container()`
|
|
1286
1295
|
published: `True` if we want the published version of the container, or
|
|
1287
1296
|
`False` for the draft version.
|
|
1297
|
+
select_related_version: An optional optimization; specify a relationship
|
|
1298
|
+
on ContainerVersion, like `componentversion` or `containerversion__x`
|
|
1299
|
+
to preload via select_related.
|
|
1288
1300
|
"""
|
|
1289
1301
|
assert isinstance(container, Container)
|
|
1290
|
-
|
|
1302
|
+
if published:
|
|
1303
|
+
# Very minor optimization: reload the container with related 1:1 entities
|
|
1304
|
+
container = Container.objects.select_related(
|
|
1305
|
+
"publishable_entity__published__version__containerversion__entity_list").get(pk=container.pk)
|
|
1306
|
+
container_version = container.versioning.published
|
|
1307
|
+
select_related = ["entity__published__version"]
|
|
1308
|
+
if select_related_version:
|
|
1309
|
+
select_related.append(f"entity__published__version__{select_related_version}")
|
|
1310
|
+
else:
|
|
1311
|
+
# Very minor optimization: reload the container with related 1:1 entities
|
|
1312
|
+
container = Container.objects.select_related(
|
|
1313
|
+
"publishable_entity__draft__version__containerversion__entity_list").get(pk=container.pk)
|
|
1314
|
+
container_version = container.versioning.draft
|
|
1315
|
+
select_related = ["entity__draft__version"]
|
|
1316
|
+
if select_related_version:
|
|
1317
|
+
select_related.append(f"entity__draft__version__{select_related_version}")
|
|
1291
1318
|
if container_version is None:
|
|
1292
1319
|
raise ContainerVersion.DoesNotExist # This container has not been published yet, or has been deleted.
|
|
1293
1320
|
assert isinstance(container_version, ContainerVersion)
|
|
1294
|
-
entity_list = []
|
|
1295
|
-
for row in container_version.entity_list.entitylistrow_set.
|
|
1321
|
+
entity_list: list[ContainerEntityListEntry] = []
|
|
1322
|
+
for row in container_version.entity_list.entitylistrow_set.select_related(
|
|
1323
|
+
"entity_version",
|
|
1324
|
+
*select_related,
|
|
1325
|
+
).order_by("order_num"):
|
|
1296
1326
|
entity_version = row.entity_version # This will be set if pinned
|
|
1297
1327
|
if not entity_version: # If this entity is "unpinned", use the latest published/draft version:
|
|
1298
1328
|
entity_version = row.entity.published.version if published else row.entity.draft.version
|
|
@@ -1385,7 +1415,10 @@ def get_containers_with_entity(
|
|
|
1385
1415
|
qs = Container.objects.filter(
|
|
1386
1416
|
publishable_entity__draft__version__containerversion__entity_list__entitylistrow__entity_id=publishable_entity_pk, # pylint: disable=line-too-long # noqa: E501
|
|
1387
1417
|
)
|
|
1388
|
-
return qs.
|
|
1418
|
+
return qs.select_related(
|
|
1419
|
+
"publishable_entity__draft__version__containerversion",
|
|
1420
|
+
"publishable_entity__published__version__containerversion",
|
|
1421
|
+
).order_by("pk").distinct() # Ordering is mostly for consistent test cases.
|
|
1389
1422
|
|
|
1390
1423
|
|
|
1391
1424
|
def get_container_children_count(
|
|
@@ -19,7 +19,7 @@ class PublishingConfig(AppConfig):
|
|
|
19
19
|
"""
|
|
20
20
|
Register Container and ContainerVersion.
|
|
21
21
|
"""
|
|
22
|
-
from .api import
|
|
22
|
+
from .api import register_publishable_models # pylint: disable=import-outside-toplevel
|
|
23
23
|
from .models import Container, ContainerVersion # pylint: disable=import-outside-toplevel
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
register_publishable_models(Container, ContainerVersion)
|
|
@@ -272,7 +272,7 @@ class PublishableEntityMixin(models.Model):
|
|
|
272
272
|
Please see docstring for PublishableEntity for more details.
|
|
273
273
|
|
|
274
274
|
If you use this class, you *MUST* also use PublishableEntityVersionMixin and
|
|
275
|
-
the publishing app's api.
|
|
275
|
+
the publishing app's api.register_publishable_models (see its docstring for
|
|
276
276
|
details).
|
|
277
277
|
"""
|
|
278
278
|
# select these related entities by default for all queries
|
|
@@ -294,6 +294,10 @@ class PublishableEntityMixin(models.Model):
|
|
|
294
294
|
def uuid(self) -> str:
|
|
295
295
|
return self.publishable_entity.uuid
|
|
296
296
|
|
|
297
|
+
@property
|
|
298
|
+
def can_stand_alone(self) -> bool:
|
|
299
|
+
return self.publishable_entity.can_stand_alone
|
|
300
|
+
|
|
297
301
|
@property
|
|
298
302
|
def key(self) -> str:
|
|
299
303
|
return self.publishable_entity.key
|
|
@@ -551,7 +555,7 @@ class PublishableEntityVersionMixin(models.Model):
|
|
|
551
555
|
Please see docstring for PublishableEntityVersion for more details.
|
|
552
556
|
|
|
553
557
|
If you use this class, you *MUST* also use PublishableEntityMixin and the
|
|
554
|
-
publishing app's api.
|
|
558
|
+
publishing app's api.register_publishable_models (see its docstring for
|
|
555
559
|
details).
|
|
556
560
|
"""
|
|
557
561
|
|
|
@@ -609,7 +613,7 @@ class PublishableContentModelRegistry:
|
|
|
609
613
|
Register what content model maps to what content version model.
|
|
610
614
|
|
|
611
615
|
If you want to call this from another app, please use the
|
|
612
|
-
``
|
|
616
|
+
``register_publishable_models`` function in this app's ``api`` module
|
|
613
617
|
instead.
|
|
614
618
|
"""
|
|
615
619
|
if not issubclass(content_model_cls, PublishableEntityMixin):
|
{openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/api.py
RENAMED
|
@@ -257,7 +257,12 @@ def get_subsections_in_section(
|
|
|
257
257
|
"""
|
|
258
258
|
assert isinstance(section, Section)
|
|
259
259
|
subsections = []
|
|
260
|
-
|
|
260
|
+
entries = publishing_api.get_entities_in_container(
|
|
261
|
+
section,
|
|
262
|
+
published=published,
|
|
263
|
+
select_related_version="containerversion__subsectionversion",
|
|
264
|
+
)
|
|
265
|
+
for entry in entries:
|
|
261
266
|
# Convert from generic PublishableEntityVersion to SubsectionVersion:
|
|
262
267
|
subsection_version = entry.entity_version.containerversion.subsectionversion
|
|
263
268
|
assert isinstance(subsection_version, SubsectionVersion)
|
{openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/sections/apps.py
RENAMED
|
@@ -19,7 +19,7 @@ class SectionsConfig(AppConfig):
|
|
|
19
19
|
"""
|
|
20
20
|
Register Section and SectionVersion.
|
|
21
21
|
"""
|
|
22
|
-
from ..publishing.api import
|
|
22
|
+
from ..publishing.api import register_publishable_models # pylint: disable=import-outside-toplevel
|
|
23
23
|
from .models import Section, SectionVersion # pylint: disable=import-outside-toplevel
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
register_publishable_models(Section, SectionVersion)
|
|
@@ -256,7 +256,12 @@ def get_units_in_subsection(
|
|
|
256
256
|
"""
|
|
257
257
|
assert isinstance(subsection, Subsection)
|
|
258
258
|
units = []
|
|
259
|
-
|
|
259
|
+
entries = publishing_api.get_entities_in_container(
|
|
260
|
+
subsection,
|
|
261
|
+
published=published,
|
|
262
|
+
select_related_version="containerversion__unitversion",
|
|
263
|
+
)
|
|
264
|
+
for entry in entries:
|
|
260
265
|
# Convert from generic PublishableEntityVersion to UnitVersion:
|
|
261
266
|
unit_version = entry.entity_version.containerversion.unitversion
|
|
262
267
|
assert isinstance(unit_version, UnitVersion)
|
|
@@ -19,7 +19,7 @@ class SubsectionsConfig(AppConfig):
|
|
|
19
19
|
"""
|
|
20
20
|
Register Subsection and SubsectionVersion.
|
|
21
21
|
"""
|
|
22
|
-
from ..publishing.api import
|
|
22
|
+
from ..publishing.api import register_publishable_models # pylint: disable=import-outside-toplevel
|
|
23
23
|
from .models import Subsection, SubsectionVersion # pylint: disable=import-outside-toplevel
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
register_publishable_models(Subsection, SubsectionVersion)
|
{openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/api.py
RENAMED
|
@@ -257,7 +257,12 @@ def get_components_in_unit(
|
|
|
257
257
|
"""
|
|
258
258
|
assert isinstance(unit, Unit)
|
|
259
259
|
components = []
|
|
260
|
-
|
|
260
|
+
entries = publishing_api.get_entities_in_container(
|
|
261
|
+
unit,
|
|
262
|
+
published=published,
|
|
263
|
+
select_related_version="componentversion",
|
|
264
|
+
)
|
|
265
|
+
for entry in entries:
|
|
261
266
|
# Convert from generic PublishableEntityVersion to ComponentVersion:
|
|
262
267
|
component_version = entry.entity_version.componentversion
|
|
263
268
|
assert isinstance(component_version, ComponentVersion)
|
{openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/apps/authoring/units/apps.py
RENAMED
|
@@ -19,7 +19,7 @@ class UnitsConfig(AppConfig):
|
|
|
19
19
|
"""
|
|
20
20
|
Register Unit and UnitVersion.
|
|
21
21
|
"""
|
|
22
|
-
from ..publishing.api import
|
|
22
|
+
from ..publishing.api import register_publishable_models # pylint: disable=import-outside-toplevel
|
|
23
23
|
from .models import Unit, UnitVersion # pylint: disable=import-outside-toplevel
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
register_publishable_models(Unit, UnitVersion)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openedx-learning
|
|
3
|
-
Version: 0.27.
|
|
3
|
+
Version: 0.27.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
|
|
@@ -19,13 +19,13 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
License-File: LICENSE.txt
|
|
22
|
-
Requires-Dist: Django
|
|
23
|
-
Requires-Dist: rules<4.0
|
|
24
|
-
Requires-Dist: celery
|
|
25
22
|
Requires-Dist: djangorestframework<4.0
|
|
26
|
-
Requires-Dist: attrs
|
|
27
23
|
Requires-Dist: tomlkit
|
|
24
|
+
Requires-Dist: celery
|
|
25
|
+
Requires-Dist: Django
|
|
26
|
+
Requires-Dist: attrs
|
|
28
27
|
Requires-Dist: edx-drf-extensions
|
|
28
|
+
Requires-Dist: rules<4.0
|
|
29
29
|
Dynamic: author
|
|
30
30
|
Dynamic: author-email
|
|
31
31
|
Dynamic: classifier
|
|
@@ -23,6 +23,7 @@ openedx_learning/apps/authoring/backup_restore/api.py
|
|
|
23
23
|
openedx_learning/apps/authoring/backup_restore/apps.py
|
|
24
24
|
openedx_learning/apps/authoring/backup_restore/models.py
|
|
25
25
|
openedx_learning/apps/authoring/backup_restore/toml.py
|
|
26
|
+
openedx_learning/apps/authoring/backup_restore/zipper.py
|
|
26
27
|
openedx_learning/apps/authoring/backup_restore/management/__init__.py
|
|
27
28
|
openedx_learning/apps/authoring/backup_restore/management/commands/__init__.py
|
|
28
29
|
openedx_learning/apps/authoring/backup_restore/management/commands/lp_dump.py
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Backup Restore API
|
|
3
|
-
"""
|
|
4
|
-
import zipfile
|
|
5
|
-
|
|
6
|
-
from openedx_learning.apps.authoring.publishing.api import get_learning_package_by_key
|
|
7
|
-
|
|
8
|
-
from .toml import TOMLLearningPackageFile
|
|
9
|
-
|
|
10
|
-
TOML_PACKAGE_NAME = "package.toml"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def create_zip_file(lp_key: str, path: str) -> None:
|
|
14
|
-
"""
|
|
15
|
-
Creates a zip file with a toml file so far (WIP)
|
|
16
|
-
|
|
17
|
-
Can throw a NotFoundError at get_learning_package_by_key
|
|
18
|
-
"""
|
|
19
|
-
learning_package = get_learning_package_by_key(lp_key)
|
|
20
|
-
toml_file = TOMLLearningPackageFile(learning_package)
|
|
21
|
-
toml_file.create()
|
|
22
|
-
toml_content: str = toml_file.get()
|
|
23
|
-
with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as zipf:
|
|
24
|
-
# Add the TOML string as a file in the ZIP
|
|
25
|
-
zipf.writestr(TOML_PACKAGE_NAME, toml_content)
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Utilities for backup and restore app
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from datetime import datetime
|
|
6
|
-
from typing import Any, Dict
|
|
7
|
-
|
|
8
|
-
from tomlkit import comment, document, dumps, nl, table
|
|
9
|
-
from tomlkit.items import Table
|
|
10
|
-
|
|
11
|
-
from openedx_learning.apps.authoring.publishing.models.learning_package import LearningPackage
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class TOMLLearningPackageFile():
|
|
15
|
-
"""
|
|
16
|
-
Class to create a .toml representation of a LearningPackage instance.
|
|
17
|
-
|
|
18
|
-
This class builds a structured TOML document using `tomlkit` with metadata and fields
|
|
19
|
-
extracted from a `LearningPackage` object. The output can later be saved to a file or used elsewhere.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
def __init__(self, learning_package: LearningPackage):
|
|
23
|
-
self.doc = document()
|
|
24
|
-
self.learning_package = learning_package
|
|
25
|
-
|
|
26
|
-
def _create_header(self) -> None:
|
|
27
|
-
"""
|
|
28
|
-
Adds a comment with the current datetime to indicate when the export occurred.
|
|
29
|
-
This helps with traceability and file versioning.
|
|
30
|
-
"""
|
|
31
|
-
self.doc.add(comment(f"Datetime of the export: {datetime.now()}"))
|
|
32
|
-
self.doc.add(nl())
|
|
33
|
-
|
|
34
|
-
def _create_table(self, params: Dict[str, Any]) -> Table:
|
|
35
|
-
"""
|
|
36
|
-
Builds a TOML table section from a dictionary of key-value pairs.
|
|
37
|
-
|
|
38
|
-
Args:
|
|
39
|
-
params (Dict[str, Any]): A dictionary containing keys and values to include in the TOML table.
|
|
40
|
-
|
|
41
|
-
Returns:
|
|
42
|
-
Table: A TOML table populated with the provided keys and values.
|
|
43
|
-
"""
|
|
44
|
-
section = table()
|
|
45
|
-
for key, value in params.items():
|
|
46
|
-
section.add(key, value)
|
|
47
|
-
return section
|
|
48
|
-
|
|
49
|
-
def create(self) -> None:
|
|
50
|
-
"""
|
|
51
|
-
Populates the TOML document with a header and a table containing
|
|
52
|
-
metadata from the LearningPackage instance.
|
|
53
|
-
|
|
54
|
-
This method must be called before calling `get()`, otherwise the document will be empty.
|
|
55
|
-
"""
|
|
56
|
-
self._create_header()
|
|
57
|
-
section = self._create_table({
|
|
58
|
-
"title": self.learning_package.title,
|
|
59
|
-
"key": self.learning_package.key,
|
|
60
|
-
"description": self.learning_package.description,
|
|
61
|
-
"created": self.learning_package.created,
|
|
62
|
-
"updated": self.learning_package.updated
|
|
63
|
-
})
|
|
64
|
-
self.doc.add("learning_package", section)
|
|
65
|
-
|
|
66
|
-
def get(self) -> str:
|
|
67
|
-
"""
|
|
68
|
-
Returns:
|
|
69
|
-
str: The string representation of the generated TOML document.
|
|
70
|
-
Ensure `create()` has been called beforehand to get meaningful output.
|
|
71
|
-
"""
|
|
72
|
-
return dumps(self.doc)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openedx_learning-0.27.0 → openedx_learning-0.27.1}/openedx_learning/api/authoring_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{openedx_learning-0.27.0 → openedx_learning-0.27.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|