Skip to content

Commit

Permalink
feat: add Library Authoring MFE plugin
Browse files Browse the repository at this point in the history
Adds experimental plugin for the Library Authoring MFE
  • Loading branch information
brian-smith-tcril committed Jun 20, 2023
1 parent 0c3a4be commit 39ca568
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ community:
Plugin Status (*Experimental*, *Production*, or *Deprecated*)
=================================== ======================================================
tutor-contrib-learner-dashboard-mfe Experimental
tutor-contrib-library-authoring-mfe Experimental
tutor-contrib-blockstore-filesystem Experimental
tutor-contrib-blockstore-minio Experimental
=================================== ======================================================
Expand Down
7 changes: 7 additions & 0 deletions plugins/tutor-contrib-library-authoring-mfe/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.*.swp
!.gitignore
TODO
__pycache__
*.egg-info/
/build/
/dist/
2 changes: 2 additions & 0 deletions plugins/tutor-contrib-library-authoring-mfe/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
recursive-include tutor_library_authoring_mfe/patches *
recursive-include tutor_library_authoring_mfe/templates *
46 changes: 46 additions & 0 deletions plugins/tutor-contrib-library-authoring-mfe/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
library_authoring_mfe plugin for `Tutor <https://docs.tutor.overhang.io>`_
===================================================================================

Installation
------------

Follow these instructions to enable this microfrontend:

* Install `tutor nightly <https://github.com/overhangio/tutor/tree/nightly>`_: ``pip install -e 'git+https://github.com/overhangio/tutor.git@nightly#egg=tutor'``
* Install `tutor-mfe nightly <https://github.com/overhangio/tutor-mfe/tree/nightly>`_: ``pip install -e 'git+https://github.com/overhangio/tutor-mfe.git@nightly#egg=tutor-mfe'``
* To use blockstore with `minio <https://min.io/>`_

* Install `tutor-minio <https://github.com/overhangio/tutor-minio>`_ nightly ``pip install -e 'git+https://github.com/overhangio/tutor-minio.git@nightly#egg=tutor-minio'``
* Enable minio plugin: ``tutor plugins enable minio``
* Enable the blockstore_config_minio plugin: ``tutor plugins enable blockstore_config_minio``

* To use blockstore with django :code:`FileSystemStorage`

* Enable the blockstore_config_filesystem plugin: ``tutor plugins enable blockstore_config_filesystem``

* Enable this plugin: ``tutor plugins enable library_authoring_mfe``
* Save the tutor config: ``tutor config save``
* Build mfe image: ``tutor images build mfe`` (if you have trouble here you may need to run it with ``--no-cache``)
* Launch tutor: ``tutor local launch``

If you want to run this MFE in
`development mode <https://github.com/overhangio/tutor-mfe/#mfe-development>`_
(to make changes to the code), instead of step 9 above, do this::

cd /path/to/frontend-app-library-authoring
tutor dev run --mount=. library-authoring npm install # Ensure NPM requirements are installed into your fork.
tutor dev start --mount=. library-authoring

Setup
-----
* Ensure you have created a user: https://docs.tutor.overhang.io/local.html#creating-a-new-user-with-staff-and-admin-rights
* Ensure you have created an organization: http://studio.local.overhang.io/admin/organizations/organization/
* If you're using minio

* Log in to the `minio Web UI <http://minio.local.overhang.io>`_ (`instructions to find credentials <https://github.com/overhangio/tutor-minio#web-ui>`_)
* Create a **public** bucket for blockstore (the default configuration expects the bucket to be named :code:`blockstore`)

Usage
-----
* Log in to studio: http://studio.local.overhang.io/home/
* Click on the libraries tab
59 changes: 59 additions & 0 deletions plugins/tutor-contrib-library-authoring-mfe/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import io
import os
from setuptools import setup, find_packages

HERE = os.path.abspath(os.path.dirname(__file__))


def load_readme():
with io.open(os.path.join(HERE, "README.rst"), "rt", encoding="utf8") as f:
return f.read()


def load_about():
about = {}
with io.open(
os.path.join(HERE, "tutor_library_authoring_mfe", "__about__.py"),
"rt",
encoding="utf-8",
) as f:
exec(f.read(), about) # pylint: disable=exec-used
return about


ABOUT = load_about()


setup(
name="tutor-contrib-library-authoring-mfe",
version=ABOUT["__version__"],
url="https://github.com/openedx/frontend-app-library-authoring",
project_urls={
"Code": "https://github.com/openedx/frontend-app-library-authoring",
"Issue tracker": "https://github.com/openedx/frontend-app-library-authoring/issues",
},
license="AGPLv3",
author="Braden MacDonald",
description="library_authoring_mfe plugin for Tutor",
long_description=load_readme(),
packages=find_packages(exclude=["tests*"]),
include_package_data=True,
python_requires=">=3.7",
install_requires=["tutor"],
entry_points={
"tutor.plugin.v1": [
"library_authoring_mfe = tutor_library_authoring_mfe.plugin"
]
},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.1.0"
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LIBRARY_AUTHORING_MICROFRONTEND_URL = "http://{{ MFE_HOST }}:{{ LIBRARY_AUTHORING_MFE_APP["port"] }}/{{ LIBRARY_AUTHORING_MFE_APP["name"] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
LIBRARY_AUTHORING_MICROFRONTEND_URL = "{% if ENABLE_HTTPS %}https://{% else %}http://{% endif %}{{ MFE_HOST }}/{{ LIBRARY_AUTHORING_MFE_APP["name"] }}"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FEATURES["ENABLE_LIBRARY_AUTHORING_MICROFRONTEND"] = True
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MFE_CONFIG_OVERRIDES.setdefault("library-authoring", {})["BLOCKSTORE_COLLECTION_UUID"] = "{{BLOCKSTORE_COLLECTION_UUID}}"
MFE_CONFIG_OVERRIDES["library-authoring"]["SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL"] = "/library-authoring/xblock-bootstrap.html"
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from glob import glob
import os
import pkg_resources
import uuid

from tutor import hooks as tutor_hooks

from .__about__ import __version__

########################################
# CONFIGURATION
########################################

tutor_hooks.Filters.CONFIG_DEFAULTS.add_items(
[
("LIBRARY_AUTHORING_MICROFRONTEND_VERSION", __version__),
("LIBRARY_AUTHORING_MFE_APP", {
"name": "library-authoring",
"repository": "https://github.com/openedx/frontend-app-library-authoring",
"port": 3001,
})
]
)

tutor_hooks.Filters.CONFIG_UNIQUE.add_items(
[
("BLOCKSTORE_COLLECTION_UUID", str(uuid.uuid4()))
]
)


########################################
# INITIALIZATION TASKS
########################################

MY_INIT_TASKS: list[tuple[str, tuple[str, ...]]] = [
("cms", ("library_authoring_mfe", "jobs", "init", "cms.sh")),
]

# For each task added to MY_INIT_TASKS, we load the task template
# and add it to the CLI_DO_INIT_TASKS filter, which tells Tutor to
# run it as part of the `init` job.
for service, template_path in MY_INIT_TASKS:
full_path: str = pkg_resources.resource_filename(
"tutor_library_authoring_mfe", os.path.join("templates", *template_path)
)
with open(full_path, encoding="utf-8") as init_task_file:
init_task: str = init_task_file.read()
tutor_hooks.Filters.CLI_DO_INIT_TASKS.add_item((service, init_task))

########################################
# TEMPLATE RENDERING
########################################

tutor_hooks.Filters.ENV_TEMPLATE_ROOTS.add_items(
# Root paths for template files, relative to the project root.
[
pkg_resources.resource_filename("tutor_library_authoring_mfe", "templates"),
]
)

########################################
# PATCH LOADING
########################################

# For each file in tutor_library_authoring_mfe/patches,
# apply a patch based on the file's name and contents.
for path in glob(
os.path.join(
pkg_resources.resource_filename("tutor_library_authoring_mfe", "patches"),
"*",
)
):
with open(path, encoding="utf-8") as patch_file:
tutor_hooks.Filters.ENV_PATCHES.add_item((os.path.basename(path), patch_file.read()))

# Tutor overwrites webpack.dev.config.js, but this MFE depends on some code
# in that file to work correctly so we have to restore it here manually.
# https://github.com/openedx/frontend-app-library-authoring/blob/b95c198b/webpack.dev.config.js
tutor_hooks.Filters.ENV_PATCHES.add_item(("mfe-webpack-dev-config","""
const fs = require('fs');
// If this is the Library Authoring MFE, apply this fix:
if (fs.existsSync("src/library-authoring/edit-block/LibraryBlock/xblock-bootstrap.html")) {
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = merge(module.exports, {
plugins: [
new CopyWebpackPlugin({
patterns: [{
context: path.resolve(__dirname, 'src/library-authoring/edit-block/LibraryBlock'),
from: 'xblock-bootstrap.html',
}],
}),
],
});
}
"""))
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Enable the waffle flag to use this MFE
(./manage.py cms waffle_flag --list | grep studio.library_authoring_mfe) || ./manage.py lms waffle_flag studio.library_authoring_mfe --create --everyone

# Make sure a Blockstore "Collection" exists to hold the library content.
# the UUID is created in CONFIG_UNIQUE in plugin.py
echo "from blockstore.apps.bundles.models import Collection; coll, _ = Collection.objects.get_or_create(title='Libraries Content Collection', uuid='{{BLOCKSTORE_COLLECTION_UUID}}')" | ./manage.py cms shell

0 comments on commit 39ca568

Please sign in to comment.