Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade h5p library #2

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ node_modules/
yarn.lock
.env
h5p/content
h5p/libraries
h5p/temporary-storage
h5p/editor
h5p/core
h5p/tmp
h5p/real-content-types.json
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dockerfile
FROM node:14
FROM node:16
# 14 LTS

RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
Expand All @@ -16,4 +16,4 @@ RUN mkdir /home/node/certs

CMD ["sh", "-c", "yarn && yarn start"]

EXPOSE 80
EXPOSE 8080
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ The scores in HPI do not go down
To make use of S3 storage and a mongo database to make the application horizontally
scalable and remove all state from a single instance, we can enable saving data in mongoDB and files on AWS S3.

For the mongo DB host, make sure that:

* You specify the host like this: "mongodb://{{host}}:{{port}}"
* If you are connecting to a localhost mongo db instance, make sure that service is exposed to docker - it is not sufficient to have localhost as the port. See more [here](https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds)

You can get access to a free test MongoDB cluster [here](https://mongodb.com) to test.

Add the following to your env file and the application will do the rest:

```
Expand Down
101 changes: 101 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
version: "3.1"
services:
app:
depends_on:
- mongo
- minio
- minio_init
- redis
build: "./"
container_name: h5p-lti-1p0-provider
working_dir: /home/node/app
ports:
- "8080:8080"
volumes:
- ./h5p:/home/node/app/h5p
- ./src:/home/node/app/src
- ./package.json:/home/node/app/package.json
environment:
NODE_ENV: development
SESSION_SECRET: sessionsecret
PORT: 8080
OAUTH_CONSUMER_KEY: oauthconsumerkey
OAUTH_SECRET: oauthsecret
REDIS_URL: redis://redis:6379
DOMAIN: localhost
TEMPORARYSTORAGE: s3
CONTENTSTORAGE: mongos3
AWS_ACCESS_KEY_ID: minioaccesskey
AWS_SECRET_ACCESS_KEY: miniosecret
AWS_S3_ENDPOINT: http://minio:9000
AWS_S3_MAX_FILE_LENGTH: 100
CONTENT_AWS_S3_BUCKET: testbucket1
TEMPORARY_AWS_S3_BUCKET: tempbucket1
MONGODB_URL: mongodb://mongo:27017
MONGODB_DB: testdb1
MONGODB_USER: root
MONGODB_PASSWORD: example
CONTENT_MONGO_COLLECTION: h5p
CACHE: redis
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_DB: 0
LIBRARYSTORAGE: mongos3
LIBRARY_MONGO_COLLECTION: h5plibraries
LIBRARY_AWS_S3_BUCKET: libbucket1
DEBUG: h5p:*
LOG_LEVEL: debug

command: sh -c "yarn && yarn download && yarn start:dev"

redis:
image: "redis:alpine"
container_name: redis
command: "redis-server --appendonly yes"
volumes:
- redis_data:/data

# Creates buckets for S3
minio_init:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "
/usr/bin/mc config host add h5pminio http://minio:9000 minioaccesskey miniosecret --api S3v4;
/usr/bin/mc mb h5pminio/testbucket1;
/usr/bin/mc mb h5pminio/tempbucket1;
/usr/bin/mc mb h5pminio/libbucket1;
exit 0;
"

mongo:
image: mongo:latest
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
volumes:
- mongodb_data:/data/db

minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
- "33515:33515"
container_name: minio
volumes:
- minio_data:/data
command: ["server", "/data"]
environment:
# MINIO_ROOT_USER: 'AKIAIOSFODNN7EXAMPLE'
# MINIO_ROOT_PASSWORD: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
MINIO_ACCESS_KEY: minioaccesskey
MINIO_SECRET_KEY: miniosecret

volumes:
mongodb_data:
minio_data:
redis_data:
h5p_data:
20 changes: 10 additions & 10 deletions h5p-config.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

{
"fetchingDisabled": 0,
"uuid": "8de62c47-f335-42f6-909d-2d8f4b7fb7f5",
"siteType": "internet",
"sendUsageStatistics": false,
"hubRegistrationEndpoint": "https://api.h5p.org/v1/sites",
"hubContentTypesEndpoint": "https://api.h5p.org/v1/content-types/",
"contentTypeCacheRefreshInterval": 86400000,
"enableLrsContentTypes": true
}
"fetchingDisabled": 0,
"uuid": "8de62c47-f335-42f6-909d-2d8f4b7fb7f5",
"siteType": "internet",
"sendUsageStatistics": false,
"contentHubEnabled": true,
"hubRegistrationEndpoint": "https://api.h5p.org/v1/sites",
"hubContentTypesEndpoint": "https://api.h5p.org/v1/content-types/",
"contentTypeCacheRefreshInterval": 86400000,
"enableLrsContentTypes": true
}
1 change: 0 additions & 1 deletion h5p/real-content-types.json

This file was deleted.

26 changes: 21 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,41 @@
"main": "server.js",
"scripts": {
"start": "node src/server",
"start:dev": "nodemon src/server",
"download": "yarn download:content-type-cache && yarn download:h5p",
"test": "jest",
"download:content-type-cache": "node scripts/update-real-content-type-cache.js",
"download:h5p": "sh scripts/install.sh"
},
"engines": {
"node": "^14.4.0",
"node": ">=15.0.0",
"yarn": "1.x"
},
"prettier": {
"trailingComma": "es5",
"tabWidth": 2,
"singleQuote": false,
"arrowParens": "avoid",
"printWidth": 80
},
"author": "Dom Starkey",
"license": "MIT",
"dependencies": {
"aws-sdk": "^2.766.0",
"@lumieducation/h5p-express": "^8.1.2",
"@lumieducation/h5p-html-exporter": "^8.1.2",
"@lumieducation/h5p-mongos3": "^8.1.2",
"@lumieducation/h5p-server": "^8.1.2",
"axios": "^0.19.2",
"body-parser": "^1.19.0",
"cache-manager": "3.4.4",
"cache-manager-redis-store": "2.0.0",
"connect-redis": "^4.0.4",
"crc": "^3.8.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-fileupload": "^1.1.7-alpha.3",
"express-fileupload": "^1.2.1",
"express-session": "^1.16.2",
"fs-extra": "^9.0.1",
"h5p-nodejs-library": "^4.1.2",
"helmet": "^3.23.3",
"https": "^1.0.0",
"i18next": "^19.5.1",
Expand All @@ -36,20 +48,24 @@
"ims-lti": "^3.0.2",
"merge": "^1.2.1",
"mimetype": "^0.0.8",
"mongodb": "^3.6.2",
"pug": "^2.0.4",
"qs": "^6.9.4",
"redis": "^3.0.2",
"saslprep": "^1.0.3",
"util": "^0.12.3"
},
"devDependencies": {
"jest": "^26.1.0",
"nodemon": "^2.0.12",
"supertest": "^4.0.2"
},
"jest": {
"testEnvironment": "node",
"coveragePathIgnorePatterns": [
"/node_modules/"
]
},
"volta": {
"node": "16.5.0"
}
}
2 changes: 1 addition & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# If the editor and core files are missing, we download them from GitHub.
if [ ! -d "h5p/editor" ] || [ ! -d "h5p/core" ]
then
sh scripts/download-core.sh 1.24.0 1.24.1
sh scripts/download-core.sh affaa83b51828be13e175c8ba1a7085ba9692d1d 7bc192798f8f6e1dee34891b56f3bf60ab320f3d
else
echo "Not downloading H5P Core and Editor files as they are already present!"
fi
28 changes: 13 additions & 15 deletions scripts/update-real-content-type-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,28 @@
* too often. Run this script to update the content type cache mockup. Expect necessary changes in the tests if the hub content changes.
*/

fsExtra = require("fs-extra");
path = require("path");
const H5P = require("h5p-nodejs-library");
const { ContentTypeCache } = require("../utils/content-type-cache-class");
fsExtra = require('fs-extra');
path = require('path');

const H5PServer = require('@lumieducation/h5p-server');
const ContentTypeCache = H5PServer.ContentTypeCache;
const H5PConfig = H5PServer.H5PConfig;
const InMemoryStorage = H5PServer.fsImplementations.InMemoryStorage;

const start = async () => {
const keyValueStorage = new H5P.fsImplementations.InMemoryStorage();
const config = new H5P.H5PConfig(keyValueStorage);
config.uuid = "8de62c47-f335-42f6-909d-2d8f4b7fb7f5";
const keyValueStorage = new InMemoryStorage();
const config = new H5PConfig(keyValueStorage);
config.uuid = '8de62c47-f335-42f6-909d-2d8f4b7fb7f5';

const contentTypeCache = new ContentTypeCache(config, keyValueStorage);
if (!(await contentTypeCache.forceUpdate())) {
console.error("Could not download content type cache from H5P Hub.");
console.error('Could not download content type cache from H5P Hub.');
return;
}

const contentTypes = await contentTypeCache.downloadContentTypesFromHub();
await fsExtra.writeJSON(
path.resolve("h5p/real-content-types.json"),
{ contentTypes }
);
console.log(
"Wrote current content type cache to h5p/real-content-types.json"
);
await fsExtra.writeJSON(path.resolve('h5p/real-content-types.json'), { contentTypes });
console.log('Wrote current content type cache to h5p/real-content-types.json');
};

start();
30 changes: 19 additions & 11 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const bodyParser = require("body-parser");
const express = require("express");
const helmet = require("helmet");
const path = require("path");
const H5P = require("h5p-nodejs-library");
const H5P = require("@lumieducation/h5p-server");
const H5PExpress = require("@lumieducation/h5p-express");
const fileUpload = require("express-fileupload");
const session = require("express-session");
const i18next = require("i18next");
Expand All @@ -17,6 +18,12 @@ const h5pInstance = require("./h5p-helpers/instance");
const h5pRender = require("./h5p-helpers/render");
const streaming = require("./streaming/middleware");

const {
h5pAjaxExpressRouter,
libraryAdministrationExpressRouter,
contentTypeCacheExpressRouter,
} = H5PExpress;

//initialize our app
const app = express();

Expand Down Expand Up @@ -44,7 +51,7 @@ app.use(
secret: process.env.SESSION_SECRET || "development",
resave: false,
saveUninitialized: true,
cookie: { secure: true, httpOnly: true, sameSite: "none" }
cookie: { secure: true, httpOnly: true, sameSite: "none" },
})
);

Expand All @@ -57,12 +64,13 @@ h5pInstance.getH5PStuff().then(({ h5pConfig, h5pEditor }) => {
h5pEditor.libraryStorage,
h5pEditor.contentStorage,
h5pConfig,
null,
["/assets/js/xapi-send.js"]
undefined,
undefined,
{ customization: { global: { scripts: ["/assets/js/xapi-send.js"] } } }
);
app.use(
fileUpload({
limits: { fileSize: h5pEditor.config.maxFileSize }
limits: { fileSize: h5pEditor.config.maxFileSize },
})
);

Expand All @@ -74,7 +82,7 @@ h5pInstance.getH5PStuff().then(({ h5pConfig, h5pEditor }) => {
// object, which means we get all of them.
app.use(
h5pEditor.config.baseUrl,
H5P.adapters.express(
h5pAjaxExpressRouter(
h5pEditor,
path.resolve("h5p/core"),
path.resolve("h5p/editor"),
Expand All @@ -92,16 +100,16 @@ h5pInstance.getH5PStuff().then(({ h5pConfig, h5pEditor }) => {
// The LibraryAdministrationExpress routes are REST endpoints that offer library
// management functionality.
app.use(
`${h5pEditor.config.baseUrl}/libraries`,
H5P.adapters.LibraryAdministrationExpressRouter(h5pEditor)
`${h5pEditor.config.baseUrl}/libraries`,
libraryAdministrationExpressRouter(h5pEditor)
);

// The ContentTypeCacheExpress routes are REST endpoints that allow updating
// the content type cache manually.
app.use(
`${h5pEditor.config.baseUrl}/content-type-cache`,
H5P.adapters.ContentTypeCacheExpressRouter(h5pEditor.contentTypeCache)
);
`${h5pEditor.config.baseUrl}/content-type-cache`,
contentTypeCacheExpressRouter(h5pEditor.contentTypeCache)
);

app.get("/h5p", h5pRender.render(h5pEditor));
});
Expand Down
Loading