Skip to content

Commit

Permalink
Merge pull request #508 from adlnet/python3-xapi-2.0
Browse files Browse the repository at this point in the history
xAPI 2.0 Update
  • Loading branch information
vbhayden authored Jun 22, 2023
2 parents b9b8a47 + 16f213d commit ea6d995
Show file tree
Hide file tree
Showing 46 changed files with 1,343 additions and 632 deletions.
95 changes: 95 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Deploy ADL LRS Application (Python)
'on':
push:
branches:
- python3-xapi-2.0
jobs:
build-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7"]
#python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

# - name: Install dependencies
# run: |
# python -m pip install --upgrade pip
# pip install ruff pytest
# if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

# - name: Lint with ruff
# run: |
# # stop the build if there are Python syntax errors or undefined names
# ruff --format=github --select=E9,F63,F7,F82 --target-version=py37 .
# # default set of ruff rules with GitHub Annotations
# ruff --format=github --target-version=py37 .

# - name: Test with pytest
# run: |
# pytest

- name: Build and test
run: |
pip3 install -r requirements.txt
./test-lrs.sh
# deploy-dev:
# runs-on: ubuntu-latest
# environment: dev
# needs: build-and-test
# steps:
# - name: Configure SSH
# run: |
# mkdir -p ~/.ssh
# echo "${{ secrets.ADLNET_DEV_SSH_KEY }}" > ~/.ssh/id_rsa
# chmod 600 ~/.ssh/id_rsa
# ssh-keyscan "${{ secrets.ADLNET_DEV_HOST }} >> ~/.ssh/known_hosts

# - name: Deploy code on Dev
# run: |
# ssh ${{ secrets.ADLNET_DEV_HOST_USER }}@${{ secrets.ADLNET_DEV_HOST }} "cd ${{ secrets.ADLNET_DEV_PROJECT_DIR }} && git pull origin ${GITHUB_REF#refs/heads/} && sudo docker-compose up -d --build"

deploy-staging:
runs-on: ubuntu-latest
environment: staging
needs:
- build-and-test
#- deploy-dev
steps:
- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ADLNET_STAGING_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan "${{ secrets.ADLNET_STAGING_HOST }}" >> ~/.ssh/known_hosts
- name: Deploy code on Staging
run: |
ssh ${{ secrets.ADLNET_STAGING_HOST_USER }}@${{ secrets.ADLNET_STAGING_HOST }} "
cd ${{ secrets.ADLNET_STAGING_PROJECT_DIR }} && \
echo 'Pulling Latest Code from Repository...' && \
git pull origin ${GITHUB_REF#refs/heads/} && \
echo 'Copying Required Config files...' && \
sudo cp /home/ubuntu/workflow/settings.ini /home/ubuntu/ADL_LRS/settings.ini && \
#sudo cp /home/ubuntu/workflow/docker/settings.ini /home/ubuntu/ADL_LRS/docker/lrs/settings.ini && \
sudo cp /home/ubuntu/workflow/.env /home/ubuntu/ADL_LRS/.env && \
echo 'Copying installing ssl certificate...' && \
sudo ./init-ssl.sh localhost && \
echo 'Rebuilding Docker Containers..' && \
sudo docker-compose stop && \
sudo docker-compose build --no-cache && \
sudo docker-compose up -d && \
echo 'deployed successfully on server'"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ media/
federated-analytics.js
lrs/celery.py
.vscode/
lrs-env/
docker-compose.dev.yml

docker/lrs/settings.ini
docker/settings.ini
Expand Down
4 changes: 2 additions & 2 deletions adl_lrs/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@
)

# Current xAPI version
XAPI_VERSION = '1.0.3'
XAPI_VERSION = '2.0.0'

XAPI_VERSIONS = ['1.0.0', '1.0.1', '1.0.2', XAPI_VERSION]
XAPI_VERSIONS = ['1.0.0', '1.0.1', '1.0.2', '1.0.3', XAPI_VERSION]

# Where to be redirected after logging in
LOGIN_REDIRECT_URL = '/me'
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ services:
args:
HOSTNAME: "${HOSTNAME}"
ports:
- "90:90"
- "441:443"
- "80:80"
- "443:443"
container_name: docker_nginx
volumes:
- ./docker/nginx/letsencrypt:/usr/share/nginx/html
Expand Down
2 changes: 1 addition & 1 deletion docker/certbot/generate.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

rm -rf ./certbot/etc
rm -rf ./docker/certbot/etc

docker-compose run certbot \
certonly --webroot \
Expand Down
2 changes: 0 additions & 2 deletions docker/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
FROM nginx:alpine

ARG LRS_ROOT
ARG HOSTNAME
ARG PORT

# Move our configuration into place
#
Expand Down
80 changes: 32 additions & 48 deletions docker/nginx/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,45 @@ events {
http {
include mime.types;
default_type application/octet-stream;
keepalive_timeout 1200s;
keepalive_requests 100000;
sendfile on;
keepalive_timeout 65;

proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;

client_body_in_file_only clean;
client_body_buffer_size 32;

# reduce the data that needs to be sent over network -- for testing environment
gzip on;
# gzip_static on;
gzip_min_length 10240;
gzip_comp_level 1;
gzip_vary on;
gzip_disable msie6;
gzip_proxied expired no-cache no-store private auth;
gzip_types
# text/html is always compressed by HttpGzipModule
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
client_max_body_size 300M;

sendfile on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/access.log debug;

server {
listen 80;
server_name _;
return 444;
}
server {
listen 443;
server_name _;

ssl_certificate /usr/share/keys/live/$HOSTNAME/fullchain.pem;
ssl_certificate_key /usr/share/keys/live/$HOSTNAME/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;

return 444;
}

server {
listen 80;
server_name $HOSTNAME;

location / {
include proxy_headers.conf;
proxy_pass http://lrs:8000;
}

# Static assets for the LRS
location /static {
autoindex on;
expires 1w;
alias /opt/lrs/lrs-static;
}
location /static/el-pagination {
autoindex on;
expires 1w;
alias /opt/lrs/ep-static;
}
location /static/admin {
autoindex on;
expires 1w;
alias /opt/lrs/admin-static;
return 301 https://$server_name$request_uri;
}

location ~ /.well-known/acme-challenge {
Expand Down Expand Up @@ -132,7 +116,6 @@ http {
proxy_read_timeout 300;

location / {

include proxy_headers.conf;
proxy_pass http://lrs:8000;
}
Expand Down Expand Up @@ -160,3 +143,4 @@ http {
}
}
}

27 changes: 15 additions & 12 deletions lrs/managers/ActivityManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ def __init__(self, data, auth=None, define=True):
self.populate(data)

def update_language_maps(self, incoming_act_def):

if self.activity is None:
return

# If there was no definition in the canonical data, and there is an
# incoming one, set it to incoming data
if 'definition' not in self.activity.canonical_data and incoming_act_def:
self.activity.canonical_data['definition'] = incoming_act_def

# Else there was existing canonical data, and there in an incoming one,
# only update lang maps (name, desc, interaction activities)
elif 'definition' in self.activity.canonical_data and incoming_act_def:
Expand All @@ -28,10 +33,12 @@ def update_language_maps(self, incoming_act_def):
if 'description' not in self.activity.canonical_data['definition']:
self.activity.canonical_data['definition']['description'] = {}

self.activity.canonical_data['definition']['name'] = dict(list(self.activity.canonical_data['definition']['name'].items()) +
list(incoming_act_def['name'].items()))
self.activity.canonical_data['definition']['description'] = dict(list(self.activity.canonical_data['definition']['description'].items()) +
list(incoming_act_def['description'].items()))
updated_name = dict(list(self.activity.canonical_data['definition']['name'].items()) + list(incoming_act_def['name'].items()))
updated_desc = dict(list(self.activity.canonical_data['definition']['description'].items()) + list(incoming_act_def['description'].items()))

self.activity.canonical_data['definition']['name'] = updated_name
self.activity.canonical_data['definition']['description'] = updated_desc

if 'scale' in incoming_act_def and 'scale' in self.activity.canonical_data['definition']:
trans = {x['id']: x['description']
for x in incoming_act_def['scale']}
Expand Down Expand Up @@ -82,21 +89,17 @@ def populate(self, data):
can_define = True
try:
# Using get or create inside try for racing issue
self.activity, act_created = Activity.objects.get_or_create(
activity_id=activity_id, authority=self.auth)
self.activity, act_created = Activity.objects.get_or_create(activity_id=activity_id, authority=self.auth)
except IntegrityError:
self.activity = Activity.objects.get(
activity_id=activity_id)
self.activity = Activity.objects.get(activity_id=activity_id)
act_created = False
# If activity DNE and cannot define - create activity without auth
else:
try:
# Using get or create inside try for racing issue
self.activity, act_created = Activity.objects.get_or_create(
activity_id=activity_id)
self.activity, act_created = Activity.objects.get_or_create(activity_id=activity_id)
except IntegrityError:
self.activity = Activity.objects.get(
activity_id=activity_id)
self.activity = Activity.objects.get(activity_id=activity_id)
act_created = False
# If you retrieved an activity that has no auth but user has define
# permissions, user becomes authority over activity
Expand Down
Loading

0 comments on commit ea6d995

Please sign in to comment.