Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: getodk/xlsform-online
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.12.1
Choose a base ref
...
head repository: getodk/xlsform-online
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
Showing with 261 additions and 119 deletions.
  1. +58 −0 .github/workflows/publish.yml
  2. +7 −0 .gitignore
  3. +16 −0 Dockerfile
  4. +30 −0 README.md
  5. +3 −3 requirements.txt
  6. +1 −1 xlsform_app/templates/upload.html
  7. +4 −4 xlsform_app/urls.py
  8. +129 −83 xlsform_app/views.py
  9. +11 −26 xlsform_prj/settings.py
  10. +2 −2 xlsform_prj/urls.py
58 changes: 58 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Publish

on: push

env:
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

# Login against a Docker registry
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

# Setup QEMU emulator to build multi-arch images
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

# Configure Buildx for Docker build
# https://github.com/docker/setup-buildx-action
- name: Set up Buildx
uses: docker/setup-buildx-action@v3

# Build and push Docker image with Buildx
# https://github.com/docker/build-push-action
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: 'linux/amd64,linux/arm64'
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/static/
/db.sqlite3
/debug.log
/debug.log.*

__pycache__/
.DS_Store
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.12.5-alpine AS build
RUN apk --update --no-cache add git
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt


FROM python:3.12.5-alpine AS runtime
WORKDIR /usr/src/app
RUN apk --update --no-cache add openjdk8-jre-base
COPY --from=build /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/
COPY . .
EXPOSE 8000
VOLUME ["/tmp_home", "/persistent_home"]
ENV DJANGO_TMP_HOME="/tmp_home"
ENV DJANGO_PERSISTENT_HOME="/persistent_home"
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "5", "--timeout", "600", "--max-requests", "25", "--max-requests-jitter", "5", "xlsform_prj.wsgi:application"]
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Overview
XLSForm Online is a Django-based web application that uses pyxform to convert a XLSForm to an ODK XForm and shows the preview of the Form in Enketo Express.

# Run locally

## Install requirements
* Python 3
* Java 8

```
pip install --requirement requirements.txt
export DJANGO_SECRET_KEY=<secret value>
export DJANGO_TMP_HOME=<location for temporary Forms>
export DJANGO_PERSISTENT_HOME=<location for permanent Forms>
python3 manage.py runserver
```

# Run in Docker
```
docker build --tag xlsform-online .
docker run --detach --publish 5001:80 xlsform-online
export DJANGO_SECRET_KEY=<secret value>
export DJANGO_TMP_HOME=<location for temporary Forms>
export DJANGO_PERSISTENT_HOME=<location for permanent Forms>
docker run -e DJANGO_SECRET_KEY=$DJANGO_SECRET_KEY -v $DJANGO_TMP_HOME:/tmp_home -v $DJANGO_PERSISTENT_HOME:/persistent_home -p 8000:8000 xlsform-online
```

# CORS

If you want to call `api/xlsform` from another application, please set the `DJANGO_CORS_ALLOWED_ORIGIN` environemnt variable, you can provide comma separated list for allowed origins e.g. `https://staging.enketo.getodk.org, http://localhost:5173`.
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Django==3.2.19
pyxform==1.12.1
gunicorn==20.1.0
Django==4.2.17
pyxform@git+https://github.com/xlsform/pyxform@master
gunicorn==22.0.0
2 changes: 1 addition & 1 deletion xlsform_app/templates/upload.html
Original file line number Diff line number Diff line change
@@ -48,7 +48,7 @@
{% if itemsets_url %}
<a href="{{ itemsets_url }}" class="btn btn-success">Download external choices CSV</a>
{% endif %}
<a href="https://enketo.getodk.org/preview?form={{ xml_url | urlencode }}" target="_blank" class="btn btn-success">Preview in browser</a>
<a href="https://staging.enketo.getodk.org/preview?form={{ xml_url | urlencode }}" target="_blank" class="btn btn-success">Preview in browser</a>
</div>
{% endif %}
{% endif %}
8 changes: 4 additions & 4 deletions xlsform_app/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from django.conf.urls import url
from django.urls import re_path
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from . import views

urlpatterns = [
url(r'^json_workbook/', views.json_workbook),
url(r'^$', views.index),
url(r'^downloads/(?P<path>.*)$', views.serve_file),
re_path(r'^$', views.index),
re_path(r'^downloads/(?P<path>.*)$', views.serve_file),
re_path(r'^api/xlsform$', views.api_xlsform),
]

urlpatterns += staticfiles_urlpatterns()
Loading