Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
branch = True
data_file = .coverage
source =
openedx_learning
openedx_tagging
src
omit =
test_settings
**/migrations/*
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ output/*/index.html
# Sphinx
docs/_build
docs/modules.rst
docs/openedx_learning.rst
docs/openedx_learning.*.rst
docs/openedx_content.rst
docs/openedx_content.*.rst

# Private requirements
requirements/private.in
Expand All @@ -66,6 +66,7 @@ dev.db*

# virtualenv
venv/
.venv/

### Visual Studio Code ###
# Generally ignore VS Code configuration, except...
Expand Down
65 changes: 34 additions & 31 deletions .importlinter
Original file line number Diff line number Diff line change
@@ -1,59 +1,62 @@
# openedx_learning is intended to be a library of apps used across multiple
# This repo is intended to be a library of apps used across multiple
# projects, and we want to ensure certain dependency relationships. Please
# think through any changes you make to this file carefully, and don't just
# casually modify these linting rules to "fix the build".

[importlinter]
root_package = openedx_learning

# This is the most basic layering for openedx_learning.
#
# The "lib" package is meant for low level utilities, field definitions, and the
# like, so it's at the bottom layer.
#
# The "core" apps are meant to be the heart of our system, with foundational
# data models and plugin interfaces. It can rely on "lib" utilities.
#
# The "contrib" apps are meant to be apps that could easily be created outside
# of openedx_learning in a separate repository, but are bundled here because
# we think they'll be generally useful. These apps may call into "core" or "lib"
# apps, but not the other way around. The "core" apps should *never* import from
# "contrib".
[importlinter:contract:openedx_learning_layering]
name = Lib / Core / Contrib Layering
root_packages =
openedx_tagging
openedx_content
openedx_core_internal

[importlinter:contract:core_internal_does_not_use_tagging]
type = layers
layers=
openedx_tagging
openedx_core_internal

[importlinter:contract:core_internal_does_not_use_content]
type = layers
layers=
openedx_learning.contrib
openedx_learning.apps
openedx_learning.lib
openedx_content
openedx_core_internal

# This is layering within our Authoring apps. Every new app should be added to
[importlinter:contract:tagging_and_content_independent]
type = layers
layers=
openedx_tagging
openedx_content

# This is layering within our Content applets. Every new applet should be added to
# this list when it it created.
[importlinter:contract:core_apps_layering]
name = Authoring App Dependency Layering
[importlinter:contract:content_apps_layering]
type = layers
layers=
# The public authoring API is at the top–none of the apps should call to it.
openedx_learning.api.authoring
# The public API is at the top–none of the apps should call to it.
openedx_content.api

# The "media_server" should not be depended upon by anything else
openedx_content.applets.media_server

# The "backup_restore" app handle the new export and import mechanism.
openedx_learning.apps.openedx_content.applets.backup_restore
openedx_content.applets.backup_restore

# The "components" app is responsible for storing versioned Components,
# which is Open edX Studio terminology maps to things like individual
# Problems, Videos, and blocks of HTML text. This is also the type we would
# associate with a single "leaf" XBlock–one that is not a container type and
# has no child elements.
openedx_learning.apps.openedx_content.applets.components
openedx_content.applets.components

# The "contents" app stores the simplest pieces of binary and text data,
# without versioning information. These belong to a single Learning Package.
openedx_learning.apps.openedx_content.applets.contents
openedx_content.applets.contents

# The "collections" app stores arbitrary groupings of PublishableEntities.
# Its only dependency should be the publishing app.
openedx_learning.apps.openedx_content.applets.collections
openedx_content.applets.collections

# The lowest layer is "publishing", which holds the basic primitives needed
# to create Learning Packages and manage the draft and publish states for
# various types of content.
openedx_learning.apps.openedx_content.applets.publishing
openedx_content.applets.publishing
3 changes: 1 addition & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ include CHANGELOG.rst
include LICENSE.txt
include README.rst
include requirements/base.in
recursive-include openedx_learning *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg *.py
recursive-include openedx_tagging *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg *.py *.yaml *.json *.csv
recursive-include src *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg *.py
15 changes: 5 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,14 @@ selfcheck: ## check that the Makefile is well-formed

extract_translations: ## extract strings to be translated, outputting .mo files
rm -rf docs/_build
cd openedx_learning && ../manage.py makemessages -l en -v1 -d django
cd openedx_learning && ../manage.py makemessages -l en -v1 -d djangojs
cd openedx_tagging && ../manage.py makemessages -l en -v1 -d django
cd openedx_tagging && ../manage.py makemessages -l en -v1 -d djangojs
./manage.py makemessages -l en -v1 -d django
./manage.py makemessages -l en -v1 -d djangojs

compile_translations: ## compile translation files, outputting .po files for each supported language
cd openedx_learning && ../manage.py compilemessages
cd openedx_tagging && ../manage.py compilemessages
./manage.py compilemessages

detect_changed_source_translations:
cd openedx_learning && i18n_tool changed
cd openedx_tagging && i18n_tool changed
cd src && i18n_tool changed

pull_translations: ## pull translations from Transifex
tx pull -a -f -t --mode reviewed
Expand All @@ -103,8 +99,7 @@ push_translations: ## push source translation files (.po) from Transifex
tx push -s

dummy_translations: ## generate dummy translation (.po) files
cd openedx_learning && i18n_tool dummy
cd openedx_tagging && i18n_tool dummy
cd src && i18n_tool dummy

build_dummy_translations: extract_translations dummy_translations compile_translations ## generate and compile dummy translation files

Expand Down
17 changes: 5 additions & 12 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,22 @@ Open edX Learning Core (and Tagging)
Overview
--------

The ``openedx_learning`` package holds Django apps that represent core learning concepts and data models that have been extracted from edx-platform. At the moment, this repo also contains the ``openedx_tagging`` package, but this will likely be moved out in the future.
The ``openedx-learning`` project holds Django apps that represent core learning platform concepts.

Motivation
----------

The short term goal of this project is to create a small, extensible core that is easier to reason about and write extensions for than edx-platform. The longer term goal is to create a more nimble core learning platform, enabling rapid experimentation and drastic changes to the learner experience that are difficult to implement with Open edX today.
The short term goal of this project is to create a small, extensible core that is easier to reason about and write extensions for than openedx-platform. The longer term goal is to create a more nimble core learning platform, enabling rapid experimentation and drastic changes to the learner experience that are difficult to implement with Open edX today.

Replacing edx-platform is explicitly *not* a goal of this project, as only a small fraction of the concepts in edx-platform make sense to carry over here. When these core concepts are extracted and the data migrated, edx-platform will import apps from this repo and make use of their public in-process APIs.
Replacing openedx-platform is explicitly *not* a goal of this project, as only a small fraction of the concepts in openedx-platform make sense to carry over here. When these core concepts are extracted and the data migrated, openedx-platform will import apps from this repo and make use of their public in-process APIs.

Architecture
------------

Parts
~~~~~

* ``openedx_learning.lib`` is for shared utilities, and may include things like custom field types, plugin registration code, etc.
* ``openedx_learning.apps`` contains our Learning Core Django apps, where foundational data structures and APIs will live. The first of these is ``authoring``, which holds apps related to the editing and publishing of learning content.
* ``openedx_tagging.core`` contains the core Tagging app, which provides data structures and apis for tagging Open edX objects.

Learning Core Package Dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Learning Core code should never import from ``edx-platform``.
Learning Core code should never import from ``openedx-platform``.

We want to be very strict about dependency management internally as well. Please read the `.importlinter config file <.importlinter>`_ file and the `Python API Conventions ADR <docs/decisions/0016-python-public-api-conventions>`_ for more details.

Expand All @@ -56,7 +49,7 @@ The structure of this repo follows [OEP-0049](https://open-edx-proposals.readthe
Code Overview
-------------

The ``openedx_learning.apps`` package contains all our Django applications.
The ``src`` folder contains all our Django applications.

Development Workflow
--------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_version(*file_paths):
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(REPO_ROOT)

VERSION = get_version('../openedx_learning', '__init__.py')
VERSION = get_version('src/openedx_core_internal', '__init__.py')

# Configure Django for autodoc usage
os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings'
Expand Down
3 changes: 1 addition & 2 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ plugins =
mypy_django_plugin.main,
mypy_drf_plugin.main
files =
openedx_learning,
openedx_tagging,
src,
tests

[mypy.plugins.django-stubs]
Expand Down
22 changes: 10 additions & 12 deletions olx_importer/management/commands/load_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@
from django.db import transaction

# Model references to remove
from openedx_learning.apps.openedx_content.applets.components import api as components_api
from openedx_learning.apps.openedx_content.applets.contents import api as contents_api
from openedx_learning.apps.openedx_content.applets.publishing import api as publishing_api
from openedx_content import api as content_api

SUPPORTED_TYPES = ["problem", "video", "html"]
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -81,20 +79,20 @@ def load_course_data(self, learning_package_key):
now = datetime.now(timezone.utc)
title = self.get_course_title()

if publishing_api.learning_package_exists(learning_package_key):
if content_api.learning_package_exists(learning_package_key):
raise CommandError(
f"{learning_package_key} already exists. "
"This command currently only supports initial import."
)

with transaction.atomic():
self.learning_package = publishing_api.create_learning_package(
self.learning_package = content_api.create_learning_package(
learning_package_key, title, created=now,
)
for block_type in SUPPORTED_TYPES:
self.import_block_type(block_type, now) #, publish_log_entry)

publishing_api.publish_all_drafts(
content_api.publish_all_drafts(
self.learning_package.id,
message="Initial Import from load_components script"
)
Expand All @@ -116,13 +114,13 @@ def create_content(self, static_local_path, now, component_version):
logger.warning(f' Static reference not found: "{real_path}"')
return # Might as well bail if we can't find the file.

content = contents_api.get_or_create_file_content(
content = content_api.get_or_create_file_content(
self.learning_package.id,
data=data_bytes,
mime_type=mime_type,
created=now,
)
components_api.create_component_version_content(
content_api.create_component_version_content(
component_version,
content.id,
key=key,
Expand All @@ -138,7 +136,7 @@ def import_block_type(self, block_type_name, now): # , publish_log_entry):
# outside of tag declarations as well.
static_files_regex = re.compile(r"""['"]\/static\/(.+?)["'\?]""")
block_data_path = self.course_data_path / block_type_name
block_type = components_api.get_or_create_component_type("xblock.v1", block_type_name)
block_type = content_api.get_or_create_component_type("xblock.v1", block_type_name)

for xml_file_path in block_data_path.glob("*.xml"):
components_found += 1
Expand All @@ -154,7 +152,7 @@ def import_block_type(self, block_type_name, now): # , publish_log_entry):
continue

display_name = block_root.attrib.get("display_name", "")
_component, component_version = components_api.create_component_and_version(
_component, component_version = content_api.create_component_and_version(
self.learning_package.id,
component_type=block_type,
local_key=local_key,
Expand All @@ -165,14 +163,14 @@ def import_block_type(self, block_type_name, now): # , publish_log_entry):

# Create the Content entry for the raw data...
text = xml_file_path.read_text('utf-8')
text_content, _created = contents_api.get_or_create_text_content(
text_content, _created = content_api.get_or_create_text_content(
self.learning_package.id,
text=text,
mime_type=f"application/vnd.openedx.xblock.v1.{block_type_name}+xml",
created=now,
)
# Add the OLX source text to the ComponentVersion
components_api.create_component_version_content(
content_api.create_component_version_content(
component_version,
text_content.pk,
key="block.xml",
Expand Down
5 changes: 0 additions & 5 deletions openedx_learning/__init__.py

This file was deleted.

17 changes: 0 additions & 17 deletions openedx_learning/api/authoring.py

This file was deleted.

24 changes: 0 additions & 24 deletions openedx_learning/api/django.py

This file was deleted.

16 changes: 0 additions & 16 deletions openedx_learning/apps/openedx_content/api.py

This file was deleted.

9 changes: 0 additions & 9 deletions openedx_learning/contrib/readme.rst

This file was deleted.

3 changes: 0 additions & 3 deletions openedx_tagging/__init__.py

This file was deleted.

Empty file removed openedx_tagging/py.typed
Empty file.
Loading
Loading