We're working on a system that can be used by different communities to help self organise, keep track of need and effectively deploy help.
Find instructions for deployment in the deployment
directory.
To get running locally and quickly, download docker, clone this repository, then start the applications using this command:
docker-compose up --build
Configuration is handled via the .env
file. Environment variables will override what's defined in the .env
file.
If DEBUG=True
, then Django's development server will be used. This server includes hot-reload functionality and additional log information. If DEBUG=False
, a production gunicorn
server will be used.
During development, you should mount your local copy of the source code into the container. This is volume mount is encapsulated in the development.yml
file. Do this by changing the command above to:
docker-compose -f docker-compose.yml -f development.yml up --build
There are a couple of key benefits to mounting the source code as a volume.
- Local changes to code get copied to the running container, enabling Django to hot-reload the application.
- Changes to the filesystem in the container get copied to your local filesystem. This becomes useful when adding apps to Django.
To execute a python command on the docker container, use a command like this:
docker exec -it tofro-django python manage.py startapp test
You can see the names of the running containers with docker ps
.
HTML is generated using Django views. Most modules of the application will have a views.py
with the Python code grabbing the data and a templates
folder containing the template files to be rendered by the views when answering the requests. Some also have a templatetags
folder defining some new filters and tags for Django's template language.
The styles and scripts of the app are build with ParcelJS from the sources in api/static-src
. The files are compiled to the api/parcel-built
, which is in Django's STATICFILES_DIRS
search path. These are then collected, along with images, by Django's collectstatic
command.
These two steps (Parcel's build and Django's collectstatic) can be run together from the main frontend build script api/build-scripts/build-frontend-assets.sh
. You will typically be running this inside the tofro-django container like so:
docker exec tofro-django /code/build_scripts/build-frontend-assets.sh
The application relies on 3rd party packages whose messages needed to be overriden. This is done by taking advantage of Django's localization system, with a special language file in the api/messages_overrides
folder, as described by this StackOverflow answer.
To override a piece of text coming from a 3rd party package:
-
Check that the piece of text is computed via Django's translation utilities. This can be a call to one of the
gettext()
methods (often aliased as_()
) or using the{% translate %}
tag. -
Grab the ID of the message. This will be the string passed to the method or tag.
-
Add an entry to the
messages_overrides/en/LC_MESSAGES/django.po
file, as such:msgid "THE_ID_FOUND_IN_THE_3RD_PARTY_PACKAGE" msgstr "THE_MESSAGE_YOU_WANT_TO_SHOW"
Pay attention to the case, as the
msgid
is case sensitive -
Compile the messages with:
docker exec -it tofro-django python3 manage.py compilemessages
To check that everything works OK, there is a manual testing plan in the TESTING.md file.
-
Coordinator completes an
Action
form choosing its priority as "HIGH" -
The saved
Action
triggers a signalpost_save_action
in notifications.signals -
post_save_action
creates a job runningnotifications.create_action_notifications
FROM THIS POINT WE ARE RUNNING ON
redis-worker
SERVER -
create_action_notifications
innotifications.notifications
runs using the createdAction
. Because we have created a high priorityAction
create_action_notifications
callscreate
innotifications.notifications.py
-
create
in notifications.notifications.py calls -
gen_subject_and_message
innotifications.utils.py
which works out the template name and then renders and returns the message content and subject using these templates. -
create
uses these values to create a new Notification andsave
it -
new
Notification
triggers signalpost_save_notification
innotifications.signals.py
-
post_save_notification
creates a redisjob
runningsend
innotifications.notifications.py
-
send
checks there are recipients, sends the notification by email and updates theNotification
's status accordingly