From 10e2a34143c362e479a54aad5e5dc9a5520f9565 Mon Sep 17 00:00:00 2001 From: "J.G. Rubingh" Date: Fri, 13 Nov 2020 15:31:14 +0100 Subject: [PATCH] Initial commit --- .gitignore | 9 + .gitmodules | 9 + requirements.txt | 7 + synthea | 1 + synthea-international | 1 + synthea-modules | 1 + webservice/apps/RUG_template/__init__.py | 1 + webservice/apps/RUG_template/admin.py | 3 + webservice/apps/RUG_template/apps.py | 8 + .../locale/en/LC_MESSAGES/django.mo | Bin 0 -> 380 bytes .../locale/en/LC_MESSAGES/django.po | 213 ++++++ .../locale/nl/LC_MESSAGES/django.mo | Bin 0 -> 4449 bytes .../locale/nl/LC_MESSAGES/django.po | 240 +++++++ webservice/apps/RUG_template/middleware.py | 38 ++ .../apps/RUG_template/migrations/__init__.py | 0 webservice/apps/RUG_template/models.py | 3 + .../static/RUG_template/images/RUG_Logo.jpg | Bin 0 -> 54367 bytes .../static/RUG_template/images/add-icon.png | Bin 0 -> 3835 bytes .../static/RUG_template/images/edit-icon.png | Bin 0 -> 7833 bytes .../images/encrypted_document.png | Bin 0 -> 1925 bytes .../static/RUG_template/images/eye-closed.png | Bin 0 -> 1122 bytes .../static/RUG_template/images/eye-open.png | Bin 0 -> 967 bytes .../static/RUG_template/images/favicon.ico | Bin 0 -> 25094 bytes .../static/RUG_template/images/flag-en.png | Bin 0 -> 1263 bytes .../static/RUG_template/images/flag-nl.png | Bin 0 -> 124 bytes .../static/RUG_template/images/minus-icon.png | Bin 0 -> 48020 bytes .../static/RUG_template/images/plus-icon.png | Bin 0 -> 51517 bytes .../static/RUG_template/images/send_email.png | Bin 0 -> 11951 bytes .../javascript/humanize-duration.min.js | 1 + .../RUG_template/javascript/javascript.js | 64 ++ .../RUG_template/javascript/jquery.formset.js | 252 +++++++ .../javascript/jquery.tablesorter.min.js | 1 + .../static/RUG_template/javascript/konami.js | 151 +++++ .../javascript/moment-with-locales.min.js | 2 + .../RUG_template/javascript/toastr.min.js | 7 + .../static/RUG_template/style/base.css | 155 +++++ .../RUG_template/style/custom_admin.css | 8 + .../static/RUG_template/style/toastr.min.css | 1 + .../apps/RUG_template/templates/400.html | 17 + .../apps/RUG_template/templates/403.html | 17 + .../apps/RUG_template/templates/404.html | 17 + .../apps/RUG_template/templates/500.html | 17 + .../templates/admin/base_site.html | 38 ++ .../apps/RUG_template/templates/base.html | 634 ++++++++++++++++++ .../apps/RUG_template/templates/index.html | 9 + .../apps/RUG_template/templates/menu.html | 10 + .../apps/RUG_template/templates/pager.html | 29 + .../templates/registration/login.html | 25 + .../registration/password_reset_complete.html | 10 + .../registration/password_reset_confirm.html | 26 + .../registration/password_reset_done.html | 13 + .../registration/password_reset_email.html | 13 + .../registration/password_reset_form.html | 21 + .../apps/RUG_template/templates/singup.html | 18 + webservice/apps/RUG_template/tests.py | 3 + webservice/apps/RUG_template/urls.py | 7 + webservice/apps/RUG_template/views.py | 7 + webservice/apps/api/__init__.py | 1 + webservice/apps/api/admin.py | 9 + webservice/apps/api/apps.py | 66 ++ webservice/apps/api/authentication.py | 72 ++ .../apps/api/locale/en/LC_MESSAGES/django.mo | Bin 0 -> 380 bytes .../apps/api/locale/en/LC_MESSAGES/django.po | 67 ++ .../apps/api/locale/nl/LC_MESSAGES/django.mo | Bin 0 -> 441 bytes .../apps/api/locale/nl/LC_MESSAGES/django.po | 67 ++ .../apps/api/migrations/0001_initial.py | 35 + webservice/apps/api/migrations/__init__.py | 0 webservice/apps/api/models.py | 70 ++ webservice/apps/api/signals.py | 24 + webservice/apps/api/tests.py | 3 + webservice/apps/api/urls.py | 71 ++ webservice/apps/api/views.py | 52 ++ webservice/apps/synthea/__init__.py | 1 + webservice/apps/synthea/admin.py | 3 + webservice/apps/synthea/apps.py | 10 + webservice/apps/synthea/forms.py | 27 + webservice/apps/synthea/lib/utils.py | 83 +++ .../apps/synthea/migrations/0001_initial.py | 32 + .../apps/synthea/migrations/__init__.py | 0 webservice/apps/synthea/models.py | 24 + .../templates/synthea/generator_form.html | 21 + .../apps/synthea/templates/synthea/index.html | 14 + .../apps/synthea/templates/synthea/menu.html | 17 + webservice/apps/synthea/tests.py | 3 + webservice/apps/synthea/urls.py | 9 + webservice/apps/synthea/views.py | 49 ++ webservice/db.sqlite3 | Bin 0 -> 151552 bytes webservice/lib/api/base.py | 45 ++ webservice/lib/api/client.py | 145 ++++ webservice/lib/models/base.py | 20 + webservice/lib/utils/emails.py | 84 +++ webservice/lib/utils/general.py | 26 + webservice/manage.py | 22 + webservice/static/images/.gitignore | 0 webservice/static/javascript/javascript.js | 1 + webservice/static/style/style.css | 1 + webservice/webservice/.env | 41 ++ webservice/webservice/.env.example | 53 ++ webservice/webservice/__init__.py | 0 webservice/webservice/asgi.py | 16 + webservice/webservice/settings.py | 166 +++++ webservice/webservice/urls.py | 36 + webservice/webservice/wsgi.py | 16 + 103 files changed, 3609 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 requirements.txt create mode 160000 synthea create mode 160000 synthea-international create mode 160000 synthea-modules create mode 100644 webservice/apps/RUG_template/__init__.py create mode 100644 webservice/apps/RUG_template/admin.py create mode 100644 webservice/apps/RUG_template/apps.py create mode 100644 webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.mo create mode 100644 webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.po create mode 100644 webservice/apps/RUG_template/locale/nl/LC_MESSAGES/django.mo create mode 100644 webservice/apps/RUG_template/locale/nl/LC_MESSAGES/django.po create mode 100644 webservice/apps/RUG_template/middleware.py create mode 100644 webservice/apps/RUG_template/migrations/__init__.py create mode 100644 webservice/apps/RUG_template/models.py create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/RUG_Logo.jpg create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/add-icon.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/edit-icon.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/encrypted_document.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/eye-closed.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/eye-open.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/favicon.ico create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/flag-en.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/flag-nl.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/minus-icon.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/plus-icon.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/images/send_email.png create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/humanize-duration.min.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/javascript.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/jquery.formset.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/jquery.tablesorter.min.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/konami.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/moment-with-locales.min.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/javascript/toastr.min.js create mode 100644 webservice/apps/RUG_template/static/RUG_template/style/base.css create mode 100644 webservice/apps/RUG_template/static/RUG_template/style/custom_admin.css create mode 100644 webservice/apps/RUG_template/static/RUG_template/style/toastr.min.css create mode 100644 webservice/apps/RUG_template/templates/400.html create mode 100644 webservice/apps/RUG_template/templates/403.html create mode 100644 webservice/apps/RUG_template/templates/404.html create mode 100644 webservice/apps/RUG_template/templates/500.html create mode 100644 webservice/apps/RUG_template/templates/admin/base_site.html create mode 100644 webservice/apps/RUG_template/templates/base.html create mode 100644 webservice/apps/RUG_template/templates/index.html create mode 100644 webservice/apps/RUG_template/templates/menu.html create mode 100644 webservice/apps/RUG_template/templates/pager.html create mode 100644 webservice/apps/RUG_template/templates/registration/login.html create mode 100644 webservice/apps/RUG_template/templates/registration/password_reset_complete.html create mode 100644 webservice/apps/RUG_template/templates/registration/password_reset_confirm.html create mode 100644 webservice/apps/RUG_template/templates/registration/password_reset_done.html create mode 100644 webservice/apps/RUG_template/templates/registration/password_reset_email.html create mode 100644 webservice/apps/RUG_template/templates/registration/password_reset_form.html create mode 100644 webservice/apps/RUG_template/templates/singup.html create mode 100644 webservice/apps/RUG_template/tests.py create mode 100644 webservice/apps/RUG_template/urls.py create mode 100644 webservice/apps/RUG_template/views.py create mode 100644 webservice/apps/api/__init__.py create mode 100644 webservice/apps/api/admin.py create mode 100644 webservice/apps/api/apps.py create mode 100644 webservice/apps/api/authentication.py create mode 100644 webservice/apps/api/locale/en/LC_MESSAGES/django.mo create mode 100644 webservice/apps/api/locale/en/LC_MESSAGES/django.po create mode 100644 webservice/apps/api/locale/nl/LC_MESSAGES/django.mo create mode 100644 webservice/apps/api/locale/nl/LC_MESSAGES/django.po create mode 100644 webservice/apps/api/migrations/0001_initial.py create mode 100644 webservice/apps/api/migrations/__init__.py create mode 100644 webservice/apps/api/models.py create mode 100644 webservice/apps/api/signals.py create mode 100644 webservice/apps/api/tests.py create mode 100644 webservice/apps/api/urls.py create mode 100644 webservice/apps/api/views.py create mode 100644 webservice/apps/synthea/__init__.py create mode 100644 webservice/apps/synthea/admin.py create mode 100644 webservice/apps/synthea/apps.py create mode 100644 webservice/apps/synthea/forms.py create mode 100644 webservice/apps/synthea/lib/utils.py create mode 100644 webservice/apps/synthea/migrations/0001_initial.py create mode 100644 webservice/apps/synthea/migrations/__init__.py create mode 100644 webservice/apps/synthea/models.py create mode 100644 webservice/apps/synthea/templates/synthea/generator_form.html create mode 100644 webservice/apps/synthea/templates/synthea/index.html create mode 100644 webservice/apps/synthea/templates/synthea/menu.html create mode 100644 webservice/apps/synthea/tests.py create mode 100644 webservice/apps/synthea/urls.py create mode 100644 webservice/apps/synthea/views.py create mode 100644 webservice/db.sqlite3 create mode 100644 webservice/lib/api/base.py create mode 100644 webservice/lib/api/client.py create mode 100644 webservice/lib/models/base.py create mode 100644 webservice/lib/utils/emails.py create mode 100644 webservice/lib/utils/general.py create mode 100755 webservice/manage.py create mode 100644 webservice/static/images/.gitignore create mode 100644 webservice/static/javascript/javascript.js create mode 100644 webservice/static/style/style.css create mode 100644 webservice/webservice/.env create mode 100644 webservice/webservice/.env.example create mode 100644 webservice/webservice/__init__.py create mode 100644 webservice/webservice/asgi.py create mode 100644 webservice/webservice/settings.py create mode 100644 webservice/webservice/urls.py create mode 100644 webservice/webservice/wsgi.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df4b189 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +venv/* +.vscode/* +static/* +__pycache__ +db.sqlite3 +doc/_build/ +doc/output/ +api_test.py +log/* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..37bf3ce --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "synthea"] + path = synthea + url = https://github.com/dHealthNL/synthea.git +[submodule "synthea-international"] + path = synthea-international + url = https://github.com/dHealthNL/synthea-international.git +[submodule "synthea-modules"] + path = synthea-modules + url = https://github.com/dHealthNL/synthea-modules.git diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..044be4c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +Django +dj-database-url +django_js_reverse +python-decouple +django-cryptography +djangorestframework +pandas diff --git a/synthea b/synthea new file mode 160000 index 0000000..16129ad --- /dev/null +++ b/synthea @@ -0,0 +1 @@ +Subproject commit 16129ad4fbef18e5c89b941e1b14a8fcf04abf07 diff --git a/synthea-international b/synthea-international new file mode 160000 index 0000000..da67258 --- /dev/null +++ b/synthea-international @@ -0,0 +1 @@ +Subproject commit da67258b54ee83e3d4ad11b5f0dfcbc5bb053e34 diff --git a/synthea-modules b/synthea-modules new file mode 160000 index 0000000..824b4d3 --- /dev/null +++ b/synthea-modules @@ -0,0 +1 @@ +Subproject commit 824b4d3182434bd20ef644a21a8bc4a828f399dc diff --git a/webservice/apps/RUG_template/__init__.py b/webservice/apps/RUG_template/__init__.py new file mode 100644 index 0000000..4d348bc --- /dev/null +++ b/webservice/apps/RUG_template/__init__.py @@ -0,0 +1 @@ +default_app_config = 'apps.RUG_template.apps.RugTemplateConfig' \ No newline at end of file diff --git a/webservice/apps/RUG_template/admin.py b/webservice/apps/RUG_template/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/webservice/apps/RUG_template/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/webservice/apps/RUG_template/apps.py b/webservice/apps/RUG_template/apps.py new file mode 100644 index 0000000..71c96ae --- /dev/null +++ b/webservice/apps/RUG_template/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + +class RugTemplateConfig(AppConfig): + name = 'apps.RUG_template' + label = 'RUG_template' + verbose_name = _('RUG Template') + verbose_name_plural = _('RUG Template') diff --git a/webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.mo b/webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..71cbdf3e9d8d54be31066ec4ad8628bc2c1f2845 GIT binary patch literal 380 zcmYL@K~KUk7=|%=+R?Lz&%}d9i{c3jGZa>EvE7z2Nc2{r&Y96JZ6W$Y{CoZuJ5A(G zp7i_Dx9RhJeDu}vIq;l#&OC>nD^HugXY4QU{MmN?lNtRkR}RH%w3NnHT4Bh@vF%H^(V-=Ii1iQ$Qo9Pt!I1Rhe%oml#`f^NEGFCKEL->Rc=KoQ6a?!10%_7(V7ey8`V`;n{war z20Z3;uifk31QV^CRQ|iq#``$=;jWunRB8aLH({)F;i8zL{=V00y-I_qTIqGAN(}v% i$^}`yHKImSZ8jEzYJOK6-VWez49^vuhS0kh1f3tbb!oc* literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.po b/webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..04a7191 --- /dev/null +++ b/webservice/apps/RUG_template/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,213 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-07-30 15:42+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: apps/RUG_template/apps.py:7 apps/RUG_template/apps.py:8 +msgid "RUG Template" +msgstr "" + +#: apps/RUG_template/templates/400.html:4 +#: apps/RUG_template/templates/400.html:5 +msgid "Oops, sorry, bad request (400)" +msgstr "" + +#: apps/RUG_template/templates/400.html:7 +#: apps/RUG_template/templates/404.html:7 +msgid "" +"Unfortunately, the link to this page does not work, the page (temporarily) " +"does not exist or it has been moved." +msgstr "" + +#: apps/RUG_template/templates/403.html:4 +#: apps/RUG_template/templates/403.html:5 +msgid "Oops, sorry, forbidden access (403)" +msgstr "" + +#: apps/RUG_template/templates/403.html:7 +msgid "Unfortunately, you do not have rights to access this url." +msgstr "" + +#: apps/RUG_template/templates/404.html:4 +#: apps/RUG_template/templates/404.html:5 +msgid "Oops, sorry, page not found (404)" +msgstr "" + +#: apps/RUG_template/templates/500.html:4 +#: apps/RUG_template/templates/500.html:5 +msgid "Oops, sorry, server error (500)" +msgstr "" + +#: apps/RUG_template/templates/500.html:7 +msgid "Unfortunately, something went wrong on the server." +msgstr "" + +#: apps/RUG_template/templates/admin/base_site.html:24 +msgid "Language" +msgstr "" + +#: apps/RUG_template/templates/admin/base_site.html:32 +msgid "Documentation" +msgstr "" + +#: apps/RUG_template/templates/admin/base_site.html:36 +msgid "Change password" +msgstr "" + +#: apps/RUG_template/templates/admin/base_site.html:38 +msgid "Log out" +msgstr "" + +#: apps/RUG_template/templates/base.html:7 +msgid "Welcome at RUG" +msgstr "" + +#: apps/RUG_template/templates/base.html:113 +msgid "Language selection" +msgstr "" + +#: apps/RUG_template/templates/index.html:4 +#: apps/RUG_template/templates/index.html:5 +msgid "Welcome to the RUG Template page" +msgstr "" + +#: apps/RUG_template/templates/index.html:7 +msgid "Simple RUG Template" +msgstr "" + +#: apps/RUG_template/templates/index.html:8 +msgid "Some more text" +msgstr "" + +#: apps/RUG_template/templates/menu.html:4 +msgid "Section" +msgstr "" + +#: apps/RUG_template/templates/menu.html:7 +msgid "Menu item" +msgstr "" + +#: apps/RUG_template/templates/pager.html:13 +msgid "previous" +msgstr "" + +#: apps/RUG_template/templates/pager.html:21 +msgid "next" +msgstr "" + +#: apps/RUG_template/templates/registration/login.html:4 +#: apps/RUG_template/templates/registration/login.html:5 +#: apps/RUG_template/templates/registration/login.html:8 +#: apps/RUG_template/templates/registration/login.html:18 +msgid "Login" +msgstr "" + +#: apps/RUG_template/templates/registration/login.html:10 +msgid "" +"You can login here to create your schedules. If you do not have a login, " +"please contact: some_one@rug.nl" +msgstr "" + +#: apps/RUG_template/templates/registration/login.html:24 +msgid "Lost password?" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_complete.html:4 +#: apps/RUG_template/templates/registration/password_reset_complete.html:5 +#: apps/RUG_template/templates/registration/password_reset_complete.html:7 +msgid "Password reset complete" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_complete.html:9 +#, python-format +msgid "" +"Your new password has been set. You can log in now on the log in page." +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:4 +#: apps/RUG_template/templates/registration/password_reset_confirm.html:5 +#: apps/RUG_template/templates/registration/password_reset_confirm.html:7 +msgid "Set a new password!" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:9 +msgid "Here you can set a new password." +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:17 +msgid "Change my password" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:23 +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_done.html:4 +#: apps/RUG_template/templates/registration/password_reset_done.html:5 +#: apps/RUG_template/templates/registration/password_reset_done.html:8 +msgid "Reset password, email sent" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_done.html:11 +msgid "" +"We've emailed you instructions for setting your password. You should receive " +"the email shortly!" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_email.html:2 +#, python-format +msgid "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s.\n" +"\n" +"Please go to the following page and choose a new password:\n" +"\n" +"%(protocol)s://%(domain)s%(reset_url)s\n" +"\n" +"Your username, in case you've forgotten: %(user)s\n" +"\n" +"Thanks for using our site!\n" +"\n" +"The %(site_name)s team" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_form.html:4 +#: apps/RUG_template/templates/registration/password_reset_form.html:5 +#: apps/RUG_template/templates/registration/password_reset_form.html:8 +msgid "Reset password" +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_form.html:10 +msgid "" +"Here you can request a password reset. Please enter your email address that " +"is used for registration." +msgstr "" + +#: apps/RUG_template/templates/registration/password_reset_form.html:17 +msgid "Reset my password" +msgstr "" + +#: apps/RUG_template/templates/singup.html:4 +#: apps/RUG_template/templates/singup.html:5 +#: apps/RUG_template/templates/singup.html:7 +#: apps/RUG_template/templates/singup.html:14 +msgid "Singup" +msgstr "" diff --git a/webservice/apps/RUG_template/locale/nl/LC_MESSAGES/django.mo b/webservice/apps/RUG_template/locale/nl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..6a1957dbe41e05284dce087db281c4678f7db2cf GIT binary patch literal 4449 zcmb7{%a0sa6~+rNkTh@e2+weBn7D^bx5pC?#BGlO$Byl298czvKtM9LyRNHiy1H(2 zZ&kM^LM&jz2Ev9&Nc;nA5bW4zMRtfah-DIqEfP`|{LZbap6-bwK}pr$+^YLH=R4my zr{*80PyHt1dV>4Q+}rPqqD}B8@8^eW=L1o68hio#1Q>%K0}IfAKLZu`Cin>W=&5S{ zY4F30SHKT~9q{AeQ{bcEHSlq88~hqL0?&Z2f?oyy1U?4-75pgp7WgUf-=OUC2%CNp zd<>LxHo#AVy&9hfKg75X%KQ{8zz5(4_%G0cibtLVpe{dF4q95Xn_^rVkygvj#&-jn6%AUV~V*lU41biEO65Rbrwf?6dkD{N0Y#sdy z#I)!&Q2hNJD17|^JO}<66n_3$k7aWiw?T>DEl|!g{CpO4;3vUffUDqdLE+_f@GIaO zpz!u4DCfTeN_ly$!ce+2#wyb4}~q$%h@vGZ+E;`a`igO4MYAHc^iLGk-7 zj1Zn)V6vS5GRW(2iNB%+xy0traDPDtTx=IE(V$$S!6&$dv*yC&aETwE;}*ZdVIV)x40WCu zH9k@k?fuNUxOp@mU$=vDZ1O@Esm-HX#u;^FOEu8Ba^}aS@rBa!)jaa1=&GH}Xm1qD zjFah3nXyhYrQ?_xUKK-KsMM>{n^@hqj&(`u3l|RQE}z1NoRFK@{FH9AjoGD6%={1K zO=bqc#BG}>TNV+R=KNw{qxT9|Qk*G~MJ^47VdHPzSg+?)2r_4U=|*I3w3 z`E4dc~U>*zqJYg^6|# zZmNC5K+8ZlU5Zilr17er&ZwsKO@;+xw~cIq z5v9wz(M#qW6GBpu0kSa7(SI2v>_bWr^g`SX>C*(atG>@%KeS~giXE7gZN$$izj)z_ z?C1>pXNbut(v0}dhk=OYkOxvC*;P_HlcZ5Y$#Uinh+Gl!-6=m9nz+o2@2cDPgT;%k z>S`q_s4{Ro^>*ex)5-DpvzSY8?$`CnqjVMAR`(d917zHP`C`{hNI5Ah2 z>{E0{Rg6n7#>f_8`5AdO5R*)hxsYFqSPfW<|tVxY4S`D4Kzjbz{ z9b#MAefBB?nJGM6Ij^sFqg)bw;>{}l1-0keLOeS@%qnDoASl?LhtZ#NUzNIc~_BJm)$#}iBt$oqicRKf!HS2on zIqQd|R=Z^%7KZA|VK?czYEaANDvPR0-`R%;4r|6em1nIxx9{9Iw(mlBz4Z*bqdau> zk0#h5#p^spG|ev)Xzk!?>tO%c&eO;9#GL!ab#CMX8)HUKJ>5?Wq*FSbb)L0u>^W)@ zhJI_~G6I)3TkTw(*-{r)FSowexoL7k>k^lCtcfWU8{PHpH(L?Zp)o`{P7iacIh!mRWDlRmNR8K(qpxBSP5-RMo335 zRATzBOh<*9ayaXoR%__A^*QR062duoYS?MvG$~6a%Qz?6*E$P7YGle+=)E?vW!f~_ zm*(E7(JVbImU^vO=(R{L&B?cvmXw&Og`m7?my7cfv8S*mK>kgyI^Zb zX89Buh2Cq5hxXnR;j8-ZF-y_HhHRBkK9O3}hd6pF9u!I@j7&b}R&WO$niYvlGWI~a`z^0?y$;pO(ld@4sgJl`+9V-G?M=AV2tcd*|?fhWY zh#o^YYrJ+GQA{Q+%8*P50`(i0@U_0w+^-pkYf7!8U7bVNCy8ith^l-2E#69Z4=, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-07-30 15:42+0200\n" +"PO-Revision-Date: 2020-05-27 15:59+0200\n" +"Last-Translator: Joshua Rubingh \n" +"Language-Team: \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.6\n" + +#: apps/RUG_template/apps.py:7 apps/RUG_template/apps.py:8 +msgid "RUG Template" +msgstr "RUG Template" + +#: apps/RUG_template/templates/400.html:4 +#: apps/RUG_template/templates/400.html:5 +msgid "Oops, sorry, bad request (400)" +msgstr "Oeps, sorry, pagina niet gevonden (404)" + +#: apps/RUG_template/templates/400.html:7 +#: apps/RUG_template/templates/404.html:7 +msgid "" +"Unfortunately, the link to this page does not work, the page (temporarily) " +"does not exist or it has been moved." +msgstr "" +"Helaas werkt de link naar deze pagina niet, de pagina bestaat (tijdelijk) " +"niet of is verplaatst." + +#: apps/RUG_template/templates/403.html:4 +#: apps/RUG_template/templates/403.html:5 +msgid "Oops, sorry, forbidden access (403)" +msgstr "Oeps, sorry, geen toegang (403)" + +#: apps/RUG_template/templates/403.html:7 +msgid "Unfortunately, you do not have rights to access this url." +msgstr "Helaas heb je geen rechten om toegang te krijgen tot deze URL." + +#: apps/RUG_template/templates/404.html:4 +#: apps/RUG_template/templates/404.html:5 +msgid "Oops, sorry, page not found (404)" +msgstr "Oeps, sorry, pagina niet gevonden (404)" + +#: apps/RUG_template/templates/500.html:4 +#: apps/RUG_template/templates/500.html:5 +msgid "Oops, sorry, server error (500)" +msgstr "Oeps, sorry, server error (500)" + +#: apps/RUG_template/templates/500.html:7 +msgid "Unfortunately, something went wrong on the server." +msgstr "Helaas is er iets misgegaan op de server." + +#: apps/RUG_template/templates/admin/base_site.html:24 +msgid "Language" +msgstr "Taal" + +#: apps/RUG_template/templates/admin/base_site.html:32 +msgid "Documentation" +msgstr "Documentatie" + +#: apps/RUG_template/templates/admin/base_site.html:36 +msgid "Change password" +msgstr "Verander wachtwoord" + +#: apps/RUG_template/templates/admin/base_site.html:38 +msgid "Log out" +msgstr "Logouit" + +#: apps/RUG_template/templates/base.html:7 +msgid "Welcome at RUG" +msgstr "Welkom bij de RUG" + +#: apps/RUG_template/templates/base.html:113 +msgid "Language selection" +msgstr "Taal keuze" + +#: apps/RUG_template/templates/index.html:4 +#: apps/RUG_template/templates/index.html:5 +msgid "Welcome to the RUG Template page" +msgstr "Welkom bij de RUG Template pagina" + +#: apps/RUG_template/templates/index.html:7 +msgid "Simple RUG Template" +msgstr "Simpel RUG Template" + +#: apps/RUG_template/templates/index.html:8 +msgid "Some more text" +msgstr "Nog wat tekst" + +#: apps/RUG_template/templates/menu.html:4 +msgid "Section" +msgstr "Sectie" + +#: apps/RUG_template/templates/menu.html:7 +msgid "Menu item" +msgstr "Menu item" + +#: apps/RUG_template/templates/pager.html:13 +msgid "previous" +msgstr "vorige" + +#: apps/RUG_template/templates/pager.html:21 +msgid "next" +msgstr "volgende" + +#: apps/RUG_template/templates/registration/login.html:4 +#: apps/RUG_template/templates/registration/login.html:5 +#: apps/RUG_template/templates/registration/login.html:8 +#: apps/RUG_template/templates/registration/login.html:18 +msgid "Login" +msgstr "Login" + +#: apps/RUG_template/templates/registration/login.html:10 +msgid "" +"You can login here to create your schedules. If you do not have a login, " +"please contact: some_one@rug.nl" +msgstr "" +"Hier kunt u inloggen om nieuwe roosters te maken. Als je geen login hebt " +"neem dan contact op met iemand@rug.nl" + +#: apps/RUG_template/templates/registration/login.html:24 +msgid "Lost password?" +msgstr "Wachtwoord kwijt?" + +#: apps/RUG_template/templates/registration/password_reset_complete.html:4 +#: apps/RUG_template/templates/registration/password_reset_complete.html:5 +#: apps/RUG_template/templates/registration/password_reset_complete.html:7 +msgid "Password reset complete" +msgstr "Wachtwoord reset is kompleet" + +#: apps/RUG_template/templates/registration/password_reset_complete.html:9 +#, python-format +msgid "" +"Your new password has been set. You can log in now on the log in page." +msgstr "" +"Je nieuwe wachtwoord is ingesteld. Je kunt nu inloggen via de inlog pagina." + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:4 +#: apps/RUG_template/templates/registration/password_reset_confirm.html:5 +#: apps/RUG_template/templates/registration/password_reset_confirm.html:7 +msgid "Set a new password!" +msgstr "Stel een nieuw wachtwoord in!" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:9 +msgid "Here you can set a new password." +msgstr "Hier kun je een nieuw wachtwoord instellen." + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:17 +msgid "Change my password" +msgstr "Verander mijn wachtwoord" + +#: apps/RUG_template/templates/registration/password_reset_confirm.html:23 +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" +"De link voor het opnieuw instellen van het wachtwoord was ongeldig, mogelijk " +"omdat deze al is gebruikt. Vraag een nieuwe reset van het wachtwoord aan." + +#: apps/RUG_template/templates/registration/password_reset_done.html:4 +#: apps/RUG_template/templates/registration/password_reset_done.html:5 +#: apps/RUG_template/templates/registration/password_reset_done.html:8 +msgid "Reset password, email sent" +msgstr "Wachtwoord is gereset, email is verstuurd" + +#: apps/RUG_template/templates/registration/password_reset_done.html:11 +msgid "" +"We've emailed you instructions for setting your password. You should receive " +"the email shortly!" +msgstr "" +"We hebben u een e-mail gestuurd met instructies voor het instellen van uw " +"wachtwoord. U ontvangt de e-mail binnenkort!" + +#: apps/RUG_template/templates/registration/password_reset_email.html:2 +#, python-format +msgid "" +"You're receiving this email because you requested a password reset for your " +"user account at %(site_name)s.\n" +"\n" +"Please go to the following page and choose a new password:\n" +"\n" +"%(protocol)s://%(domain)s%(reset_url)s\n" +"\n" +"Your username, in case you've forgotten: %(user)s\n" +"\n" +"Thanks for using our site!\n" +"\n" +"The %(site_name)s team" +msgstr "" +"Je ontvangt deze e-mail omdat je een wachtwoord reset hebt aangevraagd voor " +"je gebruikersaccount op%(site_name)s.\n" +"\n" +"Ga naar de volgende pagina en kies een nieuw wachtwoord:\n" +"\n" +"%(protocol)s://%(domain)s%(reset_url)s\n" +"\n" +"Uw gebruikersnaam, voor het geval u het bent vergeten: %(user)s\n" +"\n" +"Bedankt voor het gebruiken van onze site!\n" +"\n" +"Het team van %(site_name)s" + +#: apps/RUG_template/templates/registration/password_reset_form.html:4 +#: apps/RUG_template/templates/registration/password_reset_form.html:5 +#: apps/RUG_template/templates/registration/password_reset_form.html:8 +msgid "Reset password" +msgstr "Reset wachtwoord" + +#: apps/RUG_template/templates/registration/password_reset_form.html:10 +msgid "" +"Here you can request a password reset. Please enter your email address that " +"is used for registration." +msgstr "" +"Hier kunt u een wachtwoord reset aanvragen. Voer uw e-mailadres in dat wordt " +"gebruikt voor registratie." + +#: apps/RUG_template/templates/registration/password_reset_form.html:17 +msgid "Reset my password" +msgstr "Reset mijn wachtwoord" + +#: apps/RUG_template/templates/singup.html:4 +#: apps/RUG_template/templates/singup.html:5 +#: apps/RUG_template/templates/singup.html:7 +#: apps/RUG_template/templates/singup.html:14 +msgid "Singup" +msgstr "Opgeven" + +#~ msgid "Password reset" +#~ msgstr "Wachtwoord reset" diff --git a/webservice/apps/RUG_template/middleware.py b/webservice/apps/RUG_template/middleware.py new file mode 100644 index 0000000..cf9f7d3 --- /dev/null +++ b/webservice/apps/RUG_template/middleware.py @@ -0,0 +1,38 @@ +import pytz +import requests + +from ipware import get_client_ip +from django.utils import timezone + +# make sure you add `TimezoneMiddleware` appropriately in settings.py: 'apps.RUG_template.middleware.TimezoneMiddleware' +class TimezoneMiddleware: + """ Middleware to check user timezone. """ + def __init__(self, get_response): + self.get_response = get_response + # One-time configuration and initialization. + + def __call__(self, request): + # Code to be executed for each request before + # the view (and later middleware) are called. + client_ip, is_routable = get_client_ip(request) + user_time_zone = request.session.get('user_time_zone', None) + try: + if user_time_zone is None and is_routable and client_ip is not None: + # Here we use an online service to get visitor info. Maybe not the nicest way to do it, but it is a way + # Also we only check when we get a public IP address. Local networks will not be checked online + # https://freegeoip.app + freegeoip_response = requests.get('https://freegeoip.app/json/{0}'.format(client_ip)) + freegeoip_response_json = freegeoip_response.json() + user_time_zone = freegeoip_response_json['time_zone'] + if user_time_zone: + request.session['user_time_zone'] = user_time_zone + timezone.activate(pytz.timezone(user_time_zone)) + except: + pass + + response = self.get_response(request) + + # Code to be executed for each request/response after + # the view is called. + + return response \ No newline at end of file diff --git a/webservice/apps/RUG_template/migrations/__init__.py b/webservice/apps/RUG_template/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webservice/apps/RUG_template/models.py b/webservice/apps/RUG_template/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/webservice/apps/RUG_template/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/webservice/apps/RUG_template/static/RUG_template/images/RUG_Logo.jpg b/webservice/apps/RUG_template/static/RUG_template/images/RUG_Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..da3037b81b73290bb7a0f6e65f17deef4729bffc GIT binary patch literal 54367 zcmb5Wby%D+^C-Hwl@_N!vEnRH+^x9#0>vE`cP;K-+}&*{?oix{`(nl2U3=;Gd(QpN zInVv)&OVzbnPg@&$t3SgGW-5r{QC!hAtNCz0f2#l0Z6@l0DqSOq5#;pA`HyG6!ss$ z!~IJU;Njum5fKm(|MNvcK}JMEK|(}CMngtH{ReNkcW9{Z{uTZ)`5#hP1UNVZR3t>C z|1|mkmHh1iU?KyGU^U@jFafZbFmRYKfBOK$02lx)+`sMt{udx2BOs!@_3>Zzr#Jk6 zs{dCd0Dyo92akmORtp8ZgL|vRfWrU)U|Jrph|Jt$*U$c7)SE8nG<*@$A2rY3eUPCg z&6!x0h3{OidH-J?|9cKLZk{hEc8_cH>hxBtnWP~=G09o++X^2(K}piu*c@;@q4E2L zno-qS?1cV2u*qyAr+WR@|IXmQd5lEU-B6I%&3LT?f9zU=d+7cJgLlujA0><7F%A)f zEecjy+1F5ahAld={}TNlIi&MF5Z^S&uf2_5{Qv+G-^|2;rezj=BG=vS!A{aN;IX9Gg8k4S zG+Dq7KAUUHeDyBSYz&|5RD-R>nL%!l`}W1^Bmp*?LYhdq1PL9hLv1RGkuNaam?KwQw zpSt+=vP7p+5c>zpIlO*eAD-=$%YQp{Y13 zvcp#R*JX}$J71RhABv9T=PXF-n5AaePdv(yY}>R9J-s*T&ZCXttK|HSmIr3vlaicG zTpi9$INId!YjD!}WW;d+T{+Fu2h&}7vtSk=xRFuX1g{eRB*cUyr6ZVtaDK;>}3=I-U_&xPH+ASYu{;18$ttOJGA)$d*7GHyj* zk}CW(Xl;|yM~m#N`JFNnC*))=agO|rwscmCJ&i84xWyIyj#7-qdRxM!ZoWt{=~=8c z=I&Q%cYHhO)RwErg6uBdXT2}KJ55~WAD(DU$v5Yb!3k{AjcWqxv=%&8m!(wG?p%WV zE^ZH}&}MdrdD%gEHfbhhAWyV%{ZYH@ttucjaLX1is%^vJbcAnCn~vjmfdEhry|dV8z_1 zg1Q+u?iZKX1|)gaE5d2nqT6cKQ9w1LeLb^lYv*Vn0U#0I;89nq_O* zU$o&XX$aioxqw*1yJF__cgzJHD2}(GKdXwzmenGqE%S(Ug67( z_6h%E_Xg-lD&2||9m#(I%ipj62ldtqxPJXzIzk-*VyCxX`@J(Yx;=aU{bl>o@{j$H zmAlE!3ahGE7KQX&*3YX?f8KgR6x|BaWU8C2aLW?R=^_IFV%d)!aJ+lz?kZ}{qh@b* zZlf;rNTV(}Pi)^dlA-0Ksv}E8sD zxyUi0Z%ft&evdwt65K^P(LOH!g=XA3bge0J&)9MT^XG0%1UuvOb}&BxKxkG!hg9~6 zmY+h(^`?t{0D$9k@h-!C?Y7)&Ve|^yp9w0$ zsuOWR(-s(}D{^XB=hMhJ@V0AQ9{oUEmh{@jF0JD7owc)iMZMKG9sq#L!a0+c(BjM} zGTkH*%A9hIuGZ_NhMSKb+-9^ zmq+C@VW-%&+?qU{r$mN~l|XOa!UrD5@$kd7V!h`gNz0eDU!zy;z5{(|xRZjuIT{M1 zeLM-$H^lR`=g;ryP+Aot6@Xd!6XT9!Z%S49C$R~SMDT4^s6b~4lu1D1i#mCrH^eHT zU=i%&Kxa2+5v2m<-+atqAtpn4{?BV+|&A&Yw zHW(xT!*Djs#^YQh|Cj|+=83nW$$fnU6fK&AEWc@4WIdxB>u^79v_|K$6%uKn(OLF- zC6?`t-oHVQHQt<6uUb1BtD9(e-?3QqfNDEegNxX|wqx^{cmWiyJkJsxeMpg?PjBLU zFCbH)+tWRIRYjrh_O_Nisy>k(JY50+VpF##`073x8hmnj9iaNU_I!l!eb(n_E|vrt zir8lG;}xsxiJozM(W|eJi8pi-fa;`k{O~_jYYlonH7ax(hr?gCU;b?r2n>V0MgdgT~_^HfRvAZ<9zoJ z8Etl;Ho2#p98;(M+fwhTX>uo_{tGZF=IP40qP%0A_yy3|j|oK-U$@Jup7;y+#{&jI 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

mj?Wk%<&r3*ndPQGR2(%3tLXJ3?j%60M;Oef>bJ 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%0D}!Vlj~Pm3`RR|eM*S+d;s)`@ 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 GT=)y@jAQix literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/static/RUG_template/images/eye-closed.png b/webservice/apps/RUG_template/static/RUG_template/images/eye-closed.png new file mode 100644 index 0000000000000000000000000000000000000000..a4e0b3c24e0dcae3b2fdd5d94860f207032473e3 GIT binary patch literal 1122 zcmV-o1fBbdP)UF&J2N?Ze}BhUS;m+(fEj=_5go?Z^X#htG{#f_zFYs=0H}%R z_}>FG##{jC08E`*Cjb=@ZFBcN|0IED02X}B_>xu!;K=uTK7ysziJ(%}D-rGfIzS89?I(w4J#>TfjAT#)c*y+TDZ$bkBIQZ2(*m(HRk40GKn-kRsNa94yOt0GWValuW0_4}dulRkkIVz(XY7c!<6Q@WL_; z<3V=G7Qj+@dvd94U#8x;6;7$y@-=}4b$AWv4z*$Qo{7V2kmN^X21MbAy z?azlRDL(qxVauh`NTuB%q9eQgT?)t|0bJ>5w^R~P)pe=waArp%rT?;lI za4siZ2wLu+$vN3n9(t;T@01G2Rs?8_sRftPz-hG5uURTrdT60hTvh|Qv?-)ua0>vB z!ailfX<}iyN0|Wbq`5P@=A|btJ0%x9^oN1MjvZ&+Cmxk106Jq#7g;6Pq<&PAU69N< zZtt~xP_Xq}Ej<%a6WCkgovBab3ZFKfgZ9+(EgNLRr2jz{W6YuuOnmaCYikWEWBOXp zW4+objAN3N8;`4EfN(f|Z&Sa)vMvP==?V|YK8ETpcCptCfId>cb`;S@)Txi!Hww$$q*S}*ESnnK zV~~0<*|BU}AH@|;s@(|jxbuNzVPlCsh16HR?l#M`6XI@TQ(Peg{yqa_ryPJ&NWHO? zaO3NydBE*m1r}~e!q(70RsoRB08*cDJeL7*6@VYHg|ArA2MS(sX5gu~LzViBr$@${oDMZxw+VcImDO|# zbhBc+YkxGM5-e5)S{_eC6g-SXkIw>b;#>2WVJ7e24{xRcWmd5sku)F7Xx)G4j|yI~ z;MPZM{rF9zno$5cu@UN;`5L$tK2CFkibCdCJA1fk- zPDrvWe}uVVXY>bS?LO9OSGxip@{qfh$qMt+WS_`hZSaf=vOed4wK@ zUOeBc-`xV(64BZ9rJw~|#KGXTrIC98KZ$5UL{k7i*x0rbvhI>?>2C#v5GhaIMh*ZH zom&YZN&t(FZo46(v=bn^WDa0u2?V;}vL~WMnP_({qm-7GquopbFT&WZ5sx;4501CF%9Z-VPxzUbS;iQ4TaLTCX$vpO~4&uZ* zcbex58)RTe0fok>3xH=LTC+>Un)$wR7Oz}iX(T41GZC!;JZpkf$dGd@ptR?7a1jw@ z(r>y*mMQ6^FZt5NHbe%`klK-mm)>L=# zsp2>w+(9`#nd;Ox!=C(16TFHWo$uRD>e8v@G5}m-uw&bDL#6MqOr#1!ls(ba%>tK?x?1{Kr!@eaJdk`hY%uhfb6m-j}CANfDc2(lc?4G z#KYzG0M@oP0UMFRy;oXsTQF;ApKJ{^rg7CL4Q`Mbj$Rdit)d|a#8Mw-E&*4#w(N_h zE;dKX%<#b~E{Mw^nojS$nx`Rh1Xt)=OCP6p>GRNS!#%evik`qCP7$`2$BtVV{%yk+ zZX&x&j?c@J!UL+lz-iKvxXwRx>;8c26`4-vJY4I?4O+JDAD1rXe@8SykArHB8`3r4Un10VX1HAwM002ovPDHLkV1mU{uyz0d literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/static/RUG_template/images/favicon.ico b/webservice/apps/RUG_template/static/RUG_template/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..bc1221834ca899becb0cedb0f0250aaf2915c4cd GIT binary patch literal 25094 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 bYEdpaimj-X4W?jO5B_R}diaF@5@Gf~ZX{pt literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/static/RUG_template/images/flag-en.png b/webservice/apps/RUG_template/static/RUG_template/images/flag-en.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab58e12441493cd65884df8aef6042d23428856 GIT binary patch literal 1263 zcmV}C zH;K{;D=SKr(&qI z@csY%L>4`(000DTNkl6W4}5Cz~uqz!IJc>i~8S9C~<)E2az@N2r~H1M%r zl1gBBUD^r^7I#~jUqu&x`(J0VrK-K}c(=K%8iv7~vlQk@`MIrnim~7A8^jT`V>sHzwgrFCrTMH zXHJK5>QBJbDCN255c{R_>}0^;XXW*pg4pQ_7SH0CW2(LXH-tqg6U>>@V`qmE*^Dtk zoC{)q%(cpjY*LKz zz1#2~h!Ktq6KT{-za$#jM>Zqlh%l@WMsA{Dhlqe9z{DH%)WM1$?*a}RK*`Wo#Efjc5M!4oU*3+yW&e0j zAGVX_;3b$YSPhyj_SAiZA=^TF0GKWXQ!oYdKVy8hrH^C!d|QOo7cB)-Fa=XE1ye8u zQ!oWnFa=XE1ye8uQ!sxI^HohvrA4z~3Z`Jb14HfnJYqW$_SkkJ4BGMQkK_(oUIAK2 z!HdMWX9n+8G%M3prhn1Kn%)Quhmx6;<>TXa0$*>X%=n_t*pA1w~@;lE6EmW zO${J_LyUq`{D2+i510{UlRRduQeY0JlW_2>xu;ys%pz^!ovEhK9-Hj)dBNkK$U&0} zJ~UwR1`rHvKsg>Q3?*b7K?n=p&7vVEg2XBL-* zJcK#x(SXh*vNik=h7Old4Q+ISjMG?zuq=a4m66RlQ)q_+E0UBrPi7pbE#=^!73iNW zIfR~ZwfGju*XM!!Nnta&f#5y{Zk}9n+6gWPG$Abegdog!9}wQQJ7xokx(?lTfqH)kKbLKx)+EwU64*qDB110?JpNd;gSRj`H;jhTq#+Cu^fb zHZW}oS!NnNlmo_XR9PoDOhq;@Z#~R9_2hiO2mB*JJp4B6q@Z&g$k5`RdAe3SfkKA9 zkn9ubVv!9pbn7fI#c`Yi89Lk+nS44H*&svD?m}~%hZzSnA?&@FkOS-Ul4#WXSj@E1 Z@E4MgxU=UFt~~$%002ovPDHLkV1j46R1*LI literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/static/RUG_template/images/flag-nl.png b/webservice/apps/RUG_template/static/RUG_template/images/flag-nl.png new file mode 100644 index 0000000000000000000000000000000000000000..bafed879a5ffd15a5192af60d64c4368cd48f7fc GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^XMnhZi5W;97XQiwq&Ne7LR=Z_x-ZIT{Qv*Ip`OVX zD5&S@;usQf`0eS1f(#5CEDF<0JeO~|y{7)c%75C&3uTTMZaV+RvhT4)pKu)mLm%s< Xvmc6b1@)7FIvG4&{an^LB{Ts5r0^+L literal 0 HcmV?d00001 diff --git a/webservice/apps/RUG_template/static/RUG_template/images/minus-icon.png b/webservice/apps/RUG_template/static/RUG_template/images/minus-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a94d7dd113279ae8ca08b8536c9e7bb56542ed58 GIT binary patch literal 48020 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�c1g2pUixsc=NZ6xvO)FGyaN)@;VH(&Bhm1XAzPJR%Q7|RP=GAB zx@A=AJlK=C21}{+F@SC@T2LMf?plo|#eMRqaF0lnYe&_9v1)bk9jzxHiCIyZF3+%R!}USj(3^j-O06e0y7-7QLbGZl2wZMs(ekDxDG_G36W z(i(Cp0HHRMh%9JlP*U(OskA}jkm$y{h?(YylQm#WO}qT)kTZ`q_Qh*Z#)7mi<6)=I z4obZZ5SrA)zJ~J3TWe}wfcjk<{Pn257 z_gJ$C;Jva$b2S}-o zaq+xME*UPSh;t99--XG8!u}G14pivnw_HR z>W#K*9R-&<1MyFoLu`x`WijebJyXxd7IU8^VVr^kb{FH)BVAd?)xjK-#WZ`7)1H!*QOFHj@Af9dFR zFcD^BW8>!KRo3gmUwaGmHu+_x{F5a+Q+>{NNAv3f!#*K8?mJ z`oWm*5VS0b3cLeJAiS1|%dAMp;MH zN9e=k1v|S;5psM2xAs(ipJiK3dMzuV&k0LLfJ?od_OD%A0flb=7|2$U`$TJi>lhw7 zlkU2&F=`~*pm!o!UvaHRrkI`2NiHB0gL}qtrCz>rvwx4lEotwEdG+jb>cFwd&&$?E zY*c!a`mS9fFYZ8&sc0|IzyX!c_WMt&3;tn6o;;dH1;rrg2dvgX+8{4oS5`=P9{~SX zgSvPr&U|sr6wm+vw6aN^ueaaNgnpPOXT9VHjioMNKKRX%?51Sa+~yC)l;Q__bBf6Z z>$ik;A>BmJ@|60UfB9$h*OvA@!V(TY^Z#%4EF?WcX$%&K0~m0Zmz{L~?#Uq_$47uG zMWWbdy}tw5TfvS+s?vM{@@T<)3_$p69wQ72gR+nrihW$siSr;0_oWj-X0-O#3HK}e_CsBZNgiRd!zbDVOjNk#C1*O`+1?1{>y6~s zc#IJ~=?&&e?HXpZGK@M#Llt_B?AymIQPIN851Q!9*2i4S+V_2PjN1I~Eokfd_PmOusm4EfyiW6#Q_{81CWexnF9E3|#d| z7pURuZnXNCyvIAh{d!IfDJXjxKmmPbR&<2r`9A%{f2?hAQvO`k9F#vR0x)aZve{m< zvSEQW=ZyR*VoVSq8ma=Z6i>$N8-I~;foEk?imppkU(>lteiVTco$iA!r*MLK!Vn@Z zsnPELzPF8t`~TmUxj%^^qRjq1fKz4XwL&X@R-B~of9IALB7~jZvlE3EZ(2p;0x0J(s|igX_v! zqJX=*TGg~8VV6XWGs)<&9|TbozUI*WoKWR5_dc$Z*AkbguwJfKk6(HIvn3-OKl>v0 zm(4MhytZVwWG^odfGxJL{Cms}$DpjS-h9L~G6objhKr-N1fuO%+Xv;7VSQpSe}84* zR#a1*WcH5zgKh z){EAJ>*rZO{Y~Rc2*o#AWFzPS?_M15x%Y9Wr3|7UAwR1l1wU1g>>a zWol&EEip*rEUxORs-`Lb$zsr&3X^N+i>E|O6!Gj6%5{bhP2&HMu!RLRclgw|A5nXs z|9nPGHMc?jA1oT77w(U!bqZrSkXS!K0mJGD%=|%Dl59U`Pd#O#LQ').text('Toggle password').insertAfter(value); + }); + + jQuery('button.password_toggle').on('click',function(event){ + event.preventDefault(); + toggle_password(this); + }); +} + +function toggle_password(button) { + button = jQuery(button); + let password_field = button.prev('input'); + let show = password_field.attr('type') == 'password'; + + password_field.attr('type',( show ? 'text' : 'password' )); + button.removeClass('password_hidden password_shown').addClass(( show ? 'password_shown' : 'password_hidden' )) +} + +function human_sizes(value) { + const units = ['B','KB','MB','GB','TB','HB']; + const unit_value = 1000; + + let counter = 0; + while (value / unit_value > 1) { + value /= unit_value; + counter++; + } + return value + '' + units[counter]; +} + +function label_required_fields() { + jQuery('input,textarea,select').filter('[required]:visible').each(function(counter,value){ + let field = jQuery(value); + jQuery('label[for="' + field.attr('id') + '"]').append('*'); + }); + + /* + jQuery('select').each(function(counter,value){ + let field = jQuery(value); + console.log(jQuery('label[for="' + field.attr('id') + '"]')); + jQuery('label[for="' + field.attr('id') + '"]').append('*'); + }); + */ +} + +jQuery(function(){ + jQuery.ajaxSetup({ + beforeSend: function(xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken')); + } + } + }); + + init_password_toggles(); + label_required_fields(); +}); \ No newline at end of file diff --git a/webservice/apps/RUG_template/static/RUG_template/javascript/jquery.formset.js b/webservice/apps/RUG_template/static/RUG_template/javascript/jquery.formset.js new file mode 100644 index 0000000..e352fe8 --- /dev/null +++ b/webservice/apps/RUG_template/static/RUG_template/javascript/jquery.formset.js @@ -0,0 +1,252 @@ +/** + * https://raw.githubusercontent.com/elo80ka/django-dynamic-formset/master/src/jquery.formset.js + * jQuery Formset 1.5-pre + * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com) + * @requires jQuery 1.2.6 or later + * + * Copyright (c) 2009, Stanislaus Madueke + * All rights reserved. + * + * Licensed under the New BSD License + * See: http://www.opensource.org/licenses/bsd-license.php + */ +;(function($) { + $.fn.formset = function(opts) + { + var options = $.extend({}, $.fn.formset.defaults, opts), + flatExtraClasses = options.extraClasses.join(' '), + totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'), + maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'), + minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS'), + childElementSelector = 'input,select,textarea,label,div', + $$ = $(this), + + applyExtraClasses = function(row, ndx) { + if (options.extraClasses) { + row.removeClass(flatExtraClasses); + row.addClass(options.extraClasses[ndx % options.extraClasses.length]); + } + }, + + updateElementIndex = function(elem, prefix, ndx) { + var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'), + replacement = prefix + '-' + ndx + '-'; + if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement)); + if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement)); + if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement)); + }, + + hasChildElements = function(row) { + return row.find(childElementSelector).length > 0; + }, + + showAddButton = function() { + return maxForms.length == 0 || // For Django versions pre 1.2 + (maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0)); + }, + + /** + * Indicates whether delete link(s) can be displayed - when total forms > min forms + */ + showDeleteLinks = function() { + return minForms.length == 0 || // For Django versions pre 1.7 + (minForms.val() == '' || (totalForms.val() - minForms.val() > 0)); + }, + + insertDeleteLink = function(row) { + var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'), + addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.'); + + var delButtonHTML = '' + options.deleteText +''; + if (options.deleteContainerClass) { + // If we have a specific container for the remove button, + // place it as the last child of that container: + row.find('[class*="' + options.deleteContainerClass + '"]').append(delButtonHTML); + } else if (row.is('TR')) { + // If the forms are laid out in table rows, insert + // the remove button into the last table cell: + row.children(':last').append(delButtonHTML); + } else if (row.is('UL') || row.is('OL')) { + // If they're laid out as an ordered/unordered list, + // insert an

  • after the last list item: + row.append('
  • ' + delButtonHTML + '
  • '); + } else { + // Otherwise, just insert the remove button as the + // last child element of the form's container: + row.append(delButtonHTML); + } + + // Check if we're under the minimum number of forms - not to display delete link at rendering + if (!showDeleteLinks()){ + row.find('a.' + delCssSelector).hide(); + } + + row.find('a.' + delCssSelector).click(function() { + var row = $(this).parents('.' + options.formCssClass), + del = row.find('input:hidden[id $= "-DELETE"]'), + buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'), + forms; + if (del.length) { + // We're dealing with an inline formset. + // Rather than remove this form from the DOM, we'll mark it as deleted + // and hide it, then let Django handle the deleting: + del.val('on'); + row.hide(); + forms = $('.' + options.formCssClass).not(':hidden'); + totalForms.val(forms.length); + } else { + row.remove(); + // Update the TOTAL_FORMS count: + forms = $('.' + options.formCssClass).not('.formset-custom-template'); + totalForms.val(forms.length); + } + for (var i=0, formCount=forms.length; i':"",d.$headers=A(A.map(d.$table.find(d.selectorHeaders),function(e,t){var r,o,s,a,n,i=A(e);if(!L.getClosest(i,"tr").hasClass(d.cssIgnoreRow))return/(th|td)/i.test(e.nodeName)||(n=L.getClosest(i,"th, td"),i.attr("data-column",n.attr("data-column"))),r=L.getColumnData(d.table,d.headers,t,!0),d.headerContent[t]=i.html(),""===d.headerTemplate||i.find("."+L.css.headerIn).length||(a=d.headerTemplate.replace(L.regex.templateContent,i.html()).replace(L.regex.templateIcon,i.find("."+L.css.icon).length?"":l),d.onRenderTemplate&&(o=d.onRenderTemplate.apply(i,[t,a]))&&"string"==typeof o&&(a=o),i.html('
    '+a+"
    ")),d.onRenderHeader&&d.onRenderHeader.apply(i,[t,d,d.$table]),s=parseInt(i.attr("data-column"),10),e.column=s,n=L.getOrder(L.getData(i,r,"sortInitialOrder")||d.sortInitialOrder),d.sortVars[s]={count:-1,order:n?d.sortReset?[1,0,2]:[1,0]:d.sortReset?[0,1,2]:[0,1],lockedOrder:!1,sortedBy:""},void 0!==(n=L.getData(i,r,"lockedOrder")||!1)&&!1!==n&&(d.sortVars[s].lockedOrder=!0,d.sortVars[s].order=L.getOrder(n)?[1,1]:[0,0]),d.headerList[t]=e,i.addClass(L.css.header+" "+d.cssHeader),L.getClosest(i,"tr").addClass(L.css.headerRow+" "+d.cssHeaderRow).attr("role","row"),d.tabIndex&&i.attr("tabindex",0),e})),d.$headerIndexed=[],r=0;r'),t=n.$table.width(),s=(o=n.$tbodies.find("tr:first").children(":visible")).length,a=0;a").css("width",r));n.$table.prepend(i)}},getData:function(e,t,r){var o,s,a="",n=A(e);return n.length?(o=!!A.metadata&&n.metadata(),s=" "+(n.attr("class")||""),void 0!==n.data(r)||void 0!==n.data(r.toLowerCase())?a+=n.data(r)||n.data(r.toLowerCase()):o&&void 0!==o[r]?a+=o[r]:t&&void 0!==t[r]?a+=t[r]:" "!==s&&s.match(" "+r+"-")&&(a=s.match(new RegExp("\\s"+r+"-([\\w-]+)"))[1]||""),A.trim(a)):""},getColumnData:function(e,t,r,o,s){if("object"!=typeof t||null===t)return t;var a,n=(e=A(e)[0]).config,i=s||n.$headers,d=n.$headerIndexed&&n.$headerIndexed[r]||i.find('[data-column="'+r+'"]:last');if(void 0!==t[r])return o?t[r]:t[i.index(d)];for(a in t)if("string"==typeof a&&d.filter(a).add(d.find(a)).length)return t[a]},isProcessing:function(e,t,r){var o=(e=A(e))[0].config,s=r||e.find("."+L.css.header);t?(void 0!==r&&0'),A.fn.detach?t.detach():t.remove();var o=A(e).find("colgroup.tablesorter-savemyplace");t.insertAfter(o),o.remove(),e.isProcessing=!1},clearTableBody:function(e){A(e)[0].config.$tbodies.children().detach()},characterEquivalents:{a:"áàâãäąå",A:"ÁÀÂÃÄĄÅ",c:"çćč",C:"ÇĆČ",e:"éèêëěę",E:"ÉÈÊËĚĘ",i:"íìİîïı",I:"ÍÌİÎÏ",o:"óòôõöō",O:"ÓÒÔÕÖŌ",ss:"ß",SS:"ẞ",u:"úùûüů",U:"ÚÙÛÜŮ"},replaceAccents:function(e){var t,r="[",o=L.characterEquivalents;if(!L.characterRegex){for(t in L.characterRegexArray={},o)"string"==typeof t&&(r+=o[t],L.characterRegexArray[t]=new RegExp("["+o[t]+"]","g"));L.characterRegex=new RegExp(r+"]")}if(L.characterRegex.test(e))for(t in o)"string"==typeof t&&(e=e.replace(L.characterRegexArray[t],t));return e},validateOptions:function(e){var t,r,o,s,a="headers sortForce sortList sortAppend widgets".split(" "),n=e.originalSettings;if(n){for(t in L.debug(e,"core")&&(s=new Date),n)if("undefined"===(o=typeof L.defaults[t]))console.warn('Tablesorter Warning! "table.config.'+t+'" option not recognized');else if("object"===o)for(r in n[t])o=L.defaults[t]&&typeof L.defaults[t][r],A.inArray(t,a)<0&&"undefined"===o&&console.warn('Tablesorter Warning! "table.config.'+t+"."+r+'" option not recognized');L.debug(e,"core")&&console.log("validate options time:"+L.benchmark(s))}},restoreHeaders:function(e){var t,r,o=A(e)[0].config,s=o.$table.find(o.selectorHeaders),a=s.length;for(t=0;t tr").children("th, td");!1===t&&0<=A.inArray("uitheme",a.widgets)&&(s.triggerHandler("applyWidgetId",["uitheme"]),s.triggerHandler("applyWidgetId",["zebra"])),n.find("tr").not(i).remove(),o="sortReset update updateRows updateAll updateHeaders updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets removeWidget destroy mouseup mouseleave "+"keypress sortBegin sortEnd resetToLoadState ".split(" ").join(a.namespace+" "),s.removeData("tablesorter").unbind(o.replace(L.regex.spaces," ")),a.$headers.add(d).removeClass([L.css.header,a.cssHeader,a.cssAsc,a.cssDesc,L.css.sortAsc,L.css.sortDesc,L.css.sortNone].join(" ")).removeAttr("data-column").removeAttr("aria-label").attr("aria-disabled","true"),i.find(a.selectorSort).unbind("mousedown mouseup keypress ".split(" ").join(a.namespace+" ").replace(L.regex.spaces," ")),L.restoreHeaders(e),s.toggleClass(L.css.table+" "+a.tableClass+" tablesorter-"+a.theme,!1===t),s.removeClass(a.namespace.slice(1)),e.hasInitialized=!1,delete e.config.cache,"function"==typeof r&&r(e),L.debug(a,"core")&&console.log("tablesorter has been removed")}}};A.fn.tablesorter=function(t){return this.each(function(){var e=A.extend(!0,{},L.defaults,t,L.instanceMethods);e.originalSettings=t,!this.hasInitialized&&L.buildTable&&"TABLE"!==this.nodeName?L.buildTable(this,e):L.setup(this,e)})},window.console&&window.console.log||(L.logs=[],console={},console.log=console.warn=console.error=console.table=function(){var e=1 konami.pattern.length) { + konami.input = konami.input.substr((konami.input.length - konami.pattern.length)); + } + if (konami.input === konami.pattern) { + konami.code(konami._currentLink); + konami.input = ''; + e.preventDefault(); + return false; + } + }, + load: function (link) { + this._currentLink = link; + this.addEvent(document, "keydown", this.keydownHandler, this); + this.iphone.load(link); + }, + unload: function () { + this.removeEvent(document, 'keydown', this.keydownHandler); + this.iphone.unload(); + }, + code: function (link) { + window.location = link + }, + iphone: { + start_x: 0, + start_y: 0, + stop_x: 0, + stop_y: 0, + tap: false, + capture: false, + orig_keys: "", + keys: ["UP", "UP", "DOWN", "DOWN", "LEFT", "RIGHT", "LEFT", "RIGHT", "TAP", "TAP"], + input: [], + code: function (link) { + konami.code(link); + }, + touchmoveHandler: function (e) { + if (e.touches.length === 1 && konami.iphone.capture === true) { + var touch = e.touches[0]; + konami.iphone.stop_x = touch.pageX; + konami.iphone.stop_y = touch.pageY; + konami.iphone.tap = false; + konami.iphone.capture = false; + konami.iphone.check_direction(); + } + }, + touchendHandler: function () { + konami.iphone.input.push(konami.iphone.check_direction()); + + if (konami.iphone.input.length > konami.iphone.keys.length) konami.iphone.input.shift(); + + if (konami.iphone.input.length === konami.iphone.keys.length) { + var match = true; + for (var i = 0; i < konami.iphone.keys.length; i++) { + if (konami.iphone.input[i] !== konami.iphone.keys[i]) { + match = false; + } + } + if (match) { + konami.iphone.code(konami._currentLink); + } + } + }, + touchstartHandler: function (e) { + konami.iphone.start_x = e.changedTouches[0].pageX; + konami.iphone.start_y = e.changedTouches[0].pageY; + konami.iphone.tap = true; + konami.iphone.capture = true; + }, + load: function (link) { + this.orig_keys = this.keys; + konami.addEvent(document, "touchmove", this.touchmoveHandler); + konami.addEvent(document, "touchend", this.touchendHandler, false); + konami.addEvent(document, "touchstart", this.touchstartHandler); + }, + unload: function () { + konami.removeEvent(document, 'touchmove', this.touchmoveHandler); + konami.removeEvent(document, 'touchend', this.touchendHandler); + konami.removeEvent(document, 'touchstart', this.touchstartHandler); + }, + check_direction: function () { + x_magnitude = Math.abs(this.start_x - this.stop_x); + y_magnitude = Math.abs(this.start_y - this.stop_y); + x = ((this.start_x - this.stop_x) < 0) ? "RIGHT" : "LEFT"; + y = ((this.start_y - this.stop_y) < 0) ? "DOWN" : "UP"; + result = (x_magnitude > y_magnitude) ? x : y; + result = (this.tap === true) ? "TAP" : result; + return result; + } + } + } + + typeof callback === "string" && konami.load(callback); + if (typeof callback === "function") { + konami.code = callback; + konami.load(); + } + + return konami; +}; + + +if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Konami; +} else { + if (typeof define === 'function' && define.amd) { + define([], function() { + return Konami; + }); + } else { + window.Konami = Konami; + } +} diff --git a/webservice/apps/RUG_template/static/RUG_template/javascript/moment-with-locales.min.js b/webservice/apps/RUG_template/static/RUG_template/javascript/moment-with-locales.min.js new file mode 100644 index 0000000..877f00f --- /dev/null +++ b/webservice/apps/RUG_template/static/RUG_template/javascript/moment-with-locales.min.js @@ -0,0 +1,2 @@ +!function(e,a){"object"==typeof exports&&"undefined"!=typeof module?module.exports=a():"function"==typeof define&&define.amd?define(a):e.moment=a()}(this,function(){"use strict";var e,n;function M(){return e.apply(null,arguments)}function _(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function i(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function h(e,a){return Object.prototype.hasOwnProperty.call(e,a)}function o(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var a;for(a in e)if(h(e,a))return;return 1}function r(e){return void 0===e}function m(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function u(e,a){for(var t=[],s=0;s>>0,s=0;sFe(e)?(r=e+1,d-Fe(e)):(r=e,d);return{year:r,dayOfYear:_}}function Ce(e,a,t){var s,n,r=Je(e.year(),a,t),d=Math.floor((e.dayOfYear()-r-1)/7)+1;return d<1?s=d+Ie(n=e.year()-1,a,t):d>Ie(e.year(),a,t)?(s=d-Ie(e.year(),a,t),n=e.year()+1):(n=e.year(),s=d),{week:s,year:n}}function Ie(e,a,t){var s=Je(e,a,t),n=Je(e+1,a,t);return(Fe(e)-s+n)/7}W("w",["ww",2],"wo","week"),W("W",["WW",2],"Wo","isoWeek"),z("week","w"),z("isoWeek","W"),C("week",5),C("isoWeek",5),le("w",ae),le("ww",ae,$),le("W",ae),le("WW",ae,$),Ye(["w","ww","W","WW"],function(e,a,t,s){a[s.substr(0,1)]=G(e)});function Ue(e,a){return e.slice(a,7).concat(e.slice(0,a))}W("d",0,"do","day"),W("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),W("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),W("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),W("e",0,0,"weekday"),W("E",0,0,"isoWeekday"),z("day","d"),z("weekday","e"),z("isoWeekday","E"),C("day",11),C("weekday",11),C("isoWeekday",11),le("d",ae),le("e",ae),le("E",ae),le("dd",function(e,a){return a.weekdaysMinRegex(e)}),le("ddd",function(e,a){return a.weekdaysShortRegex(e)}),le("dddd",function(e,a){return a.weekdaysRegex(e)}),Ye(["dd","ddd","dddd"],function(e,a,t,s){var n=t._locale.weekdaysParse(e,s,t._strict);null!=n?a.d=n:L(t).invalidWeekday=e}),Ye(["d","e","E"],function(e,a,t,s){a[s]=G(e)});var Ge="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ve="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Be="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Ke=ue,qe=ue,Ze=ue;function $e(){function e(e,a){return a.length-e.length}for(var a,t,s,n,r=[],d=[],_=[],i=[],o=0;o<7;o++)a=c([2e3,1]).day(o),t=he(this.weekdaysMin(a,"")),s=he(this.weekdaysShort(a,"")),n=he(this.weekdays(a,"")),r.push(t),d.push(s),_.push(n),i.push(t),i.push(s),i.push(n);r.sort(e),d.sort(e),_.sort(e),i.sort(e),this._weekdaysRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+_.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+d.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,a){W(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),a)})}function ea(e,a){return a._meridiemParse}W("H",["HH",2],0,"hour"),W("h",["hh",2],0,Qe),W("k",["kk",2],0,function(){return this.hours()||24}),W("hmm",0,0,function(){return""+Qe.apply(this)+S(this.minutes(),2)}),W("hmmss",0,0,function(){return""+Qe.apply(this)+S(this.minutes(),2)+S(this.seconds(),2)}),W("Hmm",0,0,function(){return""+this.hours()+S(this.minutes(),2)}),W("Hmmss",0,0,function(){return""+this.hours()+S(this.minutes(),2)+S(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),z("hour","h"),C("hour",13),le("a",ea),le("A",ea),le("H",ae),le("h",ae),le("k",ae),le("HH",ae,$),le("hh",ae,$),le("kk",ae,$),le("hmm",te),le("hmmss",se),le("Hmm",te),le("Hmmss",se),Le(["H","HH"],De),Le(["k","kk"],function(e,a,t){var s=G(e);a[De]=24===s?0:s}),Le(["a","A"],function(e,a,t){t._isPm=t._locale.isPM(e),t._meridiem=e}),Le(["h","hh"],function(e,a,t){a[De]=G(e),L(t).bigHour=!0}),Le("hmm",function(e,a,t){var s=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s)),L(t).bigHour=!0}),Le("hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s,2)),a[ge]=G(e.substr(n)),L(t).bigHour=!0}),Le("Hmm",function(e,a,t){var s=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s))}),Le("Hmmss",function(e,a,t){var s=e.length-4,n=e.length-2;a[De]=G(e.substr(0,s)),a[Te]=G(e.substr(s,2)),a[ge]=G(e.substr(n))});var aa=V("Hours",!0);var ta,sa={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Se,monthsShort:je,week:{dow:0,doy:6},weekdays:Ge,weekdaysMin:Be,weekdaysShort:Ve,meridiemParse:/[ap]\.?m?\.?/i},na={},ra={};function da(e){return e?e.toLowerCase().replace("_","-"):e}function _a(e){for(var a,t,s,n,r=0;r=a&&function(e,a){for(var t=Math.min(e.length,a.length),s=0;s=a-1)break;a--}r++}return ta}function ia(a){var e=null;if(void 0===na[a]&&"undefined"!=typeof module&&module&&module.exports)try{e=ta._abbr,require("./locale/"+a),oa(e)}catch(e){na[a]=null}return na[a]}function oa(e,a){var t;return e&&((t=r(a)?ua(e):ma(e,a))?ta=t:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ta._abbr}function ma(e,a){if(null===a)return delete na[e],null;var t,s=sa;if(a.abbr=e,null!=na[e])w("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=na[e]._config;else if(null!=a.parentLocale)if(null!=na[a.parentLocale])s=na[a.parentLocale]._config;else{if(null==(t=ia(a.parentLocale)))return ra[a.parentLocale]||(ra[a.parentLocale]=[]),ra[a.parentLocale].push({name:e,config:a}),null;s=t._config}return na[e]=new H(b(s,a)),ra[e]&&ra[e].forEach(function(e){ma(e.name,e.config)}),oa(e),na[e]}function ua(e){var a;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return ta;if(!_(e)){if(a=ia(e))return a;e=[e]}return _a(e)}function la(e){var a,t=e._a;return t&&-2===L(e).overflow&&(a=t[pe]<0||11He(t[fe],t[pe])?ke:t[De]<0||24Ie(t,r,d)?L(e)._overflowWeeks=!0:null!=i?L(e)._overflowWeekday=!0:(_=Re(t,s,n,r,d),e._a[fe]=_.year,e._dayOfYear=_.dayOfYear)}(e),null!=e._dayOfYear&&(r=ga(e._a[fe],s[fe]),(e._dayOfYear>Fe(r)||0===e._dayOfYear)&&(L(e)._overflowDayOfYear=!0),t=Ne(r,0,e._dayOfYear),e._a[pe]=t.getUTCMonth(),e._a[ke]=t.getUTCDate()),a=0;a<3&&null==e._a[a];++a)e._a[a]=i[a]=s[a];for(;a<7;a++)e._a[a]=i[a]=null==e._a[a]?2===a?1:0:e._a[a];24===e._a[De]&&0===e._a[Te]&&0===e._a[ge]&&0===e._a[we]&&(e._nextDay=!0,e._a[De]=0),e._d=(e._useUTC?Ne:function(e,a,t,s,n,r,d){var _;return e<100&&0<=e?(_=new Date(e+400,a,t,s,n,r,d),isFinite(_.getFullYear())&&_.setFullYear(e)):_=new Date(e,a,t,s,n,r,d),_}).apply(null,i),n=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[De]=24),e._w&&void 0!==e._w.d&&e._w.d!==n&&(L(e).weekdayMismatch=!0)}}function va(e){if(e._f!==M.ISO_8601)if(e._f!==M.RFC_2822){e._a=[],L(e).empty=!0;for(var a,t,s,n,r,d,_,i=""+e._i,o=i.length,m=0,u=E(e._f,e._locale).match(j)||[],l=0;lt.valueOf():t.valueOf()"}),yt.toJSON=function(){return this.isValid()?this.toISOString():null},yt.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},yt.unix=function(){return Math.floor(this.valueOf()/1e3)},yt.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},yt.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},yt.eraName=function(){for(var e,a=this.localeData().eras(),t=0,s=a.length;tthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},yt.isLocal=function(){return!!this.isValid()&&!this._isUTC},yt.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},yt.isUtc=Ca,yt.isUTC=Ca,yt.zoneAbbr=function(){return this._isUTC?"UTC":""},yt.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},yt.dates=t("dates accessor is deprecated. Use date instead.",lt),yt.months=t("months accessor is deprecated. Use month instead",Ae),yt.years=t("years accessor is deprecated. Use year instead",ze),yt.zone=t("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,a){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,a),this):-this.utcOffset()}),yt.isDSTShifted=t("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e,a={};return p(a,this),(a=ba(a))._a?(e=(a._isUTC?c:Sa)(a._a),this._isDSTShifted=this.isValid()&&0=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("
    ").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e("
    "),M=e("
    "),B=e("
    "),q=e("
    "),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.3",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)}); +//# sourceMappingURL=toastr.js.map diff --git a/webservice/apps/RUG_template/static/RUG_template/style/base.css b/webservice/apps/RUG_template/static/RUG_template/style/base.css new file mode 100644 index 0000000..b4735bd --- /dev/null +++ b/webservice/apps/RUG_template/static/RUG_template/style/base.css @@ -0,0 +1,155 @@ +.rug-wrapper { + max-width: 80% !important; +} + +.rug-width-m-8-24 { + width: 25%; +} + +.rug-panel--content { + max-width: none; +} + +.rug-nav--main__item { + display: none; +} + +.rug-nav--main__item:first-of-type, +.rug-nav--main__item:last-of-type { + display: block; +} + +.rug-breadcrumbs { + display: none; +} + +p { + max-width: none; +} + +table { + width: 100%; +} + +table.stripe tr:nth-child(even) { + background-color: #f2f2f2; +} + +table.stripe td { + white-space: nowrap; + overflow: hidden; +} + +table.stripe td.empty { + text-align: center; +} + +.pointer { + cursor: pointer; +} + +form#new_schedule_form input:not([type=checkbox]) { + width: 100% +} + +.text-danger { + color: #721c24; +} + +.required { + color: red; +} + +span.required { + margin-left: 0.2rem; +} + +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} +.form-control { + display: block; + width: 100%; + height: calc(1.5em + .75rem + 2px); + padding: .375rem .75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: .25rem; + transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; +} + +.icon { + height: 1rem; + width: auto; +} + +h1 .icon { + height: 1.5rem; +} + + +/* Password toggles */ +input[readonly] { + border: none; + background-color: transparent; +/* width: 75px;*/ + } + + button.password_toggle { + width: 1.8rem; + + overflow: hidden; + text-indent: -999%; + white-space: nowrap; + cursor: pointer; + + background-color: transparent; + background-repeat: no-repeat; + background-size: auto 100%; + background-position: center; + + margin-left: 0.2rem; + border: none; + } + + button.password_toggle.password_hidden { + background-image: url('../images/eye-open.png'); + } + + button.password_toggle.password_shown { + background-image: url('../images/eye-closed.png'); + } + /* End Password toggles */ + + +.add-row { + margin: 6px 0 0 0; + padding-left: 24px; + background: url('../images/plus-icon.png') no-repeat left center; + background-size: auto 80%; +} +.delete-row { + display:block; + margin: 6px 0 0 0; + padding-left: 20px; + background: url('../images/minus-icon.png') no-repeat left center; + background-size: auto 80%; +} \ No newline at end of file diff --git a/webservice/apps/RUG_template/static/RUG_template/style/custom_admin.css b/webservice/apps/RUG_template/static/RUG_template/style/custom_admin.css new file mode 100644 index 0000000..ef1eda7 --- /dev/null +++ b/webservice/apps/RUG_template/static/RUG_template/style/custom_admin.css @@ -0,0 +1,8 @@ +img.i18n_flag { + width: 16px; + vertical-align: text-top; +} + +form#language_form { + display: inline; +} \ No newline at end of file diff --git a/webservice/apps/RUG_template/static/RUG_template/style/toastr.min.css b/webservice/apps/RUG_template/static/RUG_template/style/toastr.min.css new file mode 100644 index 0000000..643135e --- /dev/null +++ b/webservice/apps/RUG_template/static/RUG_template/style/toastr.min.css @@ -0,0 +1 @@ +/* * Note that this is toastr v2.1.3, the "latest" version in url has no more maintenance, * please go to https://cdnjs.com/libraries/toastr.js and pick a certain version you want to use, * make sure you copy the url from the website since the url may change between versions. * */ .toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#FFF}.toast-message a:hover{color:#CCC;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#FFF;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);line-height:1}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}.rtl .toast-close-button{left:-.3em;float:left;right:.3em}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999;pointer-events:none}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/400.html b/webservice/apps/RUG_template/templates/400.html new file mode 100644 index 0000000..521082f --- /dev/null +++ b/webservice/apps/RUG_template/templates/400.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Oops, sorry, bad request (400)" %}{% endblock %} +{% block pagetitle %}{% trans "Oops, sorry, bad request (400)" %}{% endblock %} +{% block content %} +

    {% trans "Unfortunately, the link to this page does not work, the page (temporarily) does not exist or it has been moved." %}

    + +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/403.html b/webservice/apps/RUG_template/templates/403.html new file mode 100644 index 0000000..a0eb5f3 --- /dev/null +++ b/webservice/apps/RUG_template/templates/403.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Oops, sorry, forbidden access (403)" %}{% endblock %} +{% block pagetitle %}{% trans "Oops, sorry, forbidden access (403)" %}{% endblock %} +{% block content %} +

    {% trans "Unfortunately, you do not have rights to access this url." %}

    + +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/404.html b/webservice/apps/RUG_template/templates/404.html new file mode 100644 index 0000000..6b0ac18 --- /dev/null +++ b/webservice/apps/RUG_template/templates/404.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Oops, sorry, page not found (404)" %}{% endblock %} +{% block pagetitle %}{% trans "Oops, sorry, page not found (404)" %}{% endblock %} +{% block content %} +

    {% trans "Unfortunately, the link to this page does not work, the page (temporarily) does not exist or it has been moved." %}

    + +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/500.html b/webservice/apps/RUG_template/templates/500.html new file mode 100644 index 0000000..643343b --- /dev/null +++ b/webservice/apps/RUG_template/templates/500.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Oops, sorry, server error (500)" %}{% endblock %} +{% block pagetitle %}{% trans "Oops, sorry, server error (500)" %}{% endblock %} +{% block content %} +

    {% trans "Unfortunately, something went wrong on the server." %}

    + +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/admin/base_site.html b/webservice/apps/RUG_template/templates/admin/base_site.html new file mode 100644 index 0000000..5fd133f --- /dev/null +++ b/webservice/apps/RUG_template/templates/admin/base_site.html @@ -0,0 +1,38 @@ +{% extends "admin/base_site.html" %} + +{% load static %} +{% load i18n %} + +{% block extrahead %} + + +{% endblock %} + +{% block userlinks %} + {% comment %} Language choice. Should be put somewhere else when finale designs are done. {% endcomment %} +
    + {% csrf_token %} + {% get_current_language as LANGUAGE_CODE %} + {% get_available_languages as LANGUAGES %} + {% get_language_info_list for LANGUAGES as languages %} + + + {% for language in languages %} + + {% with 'RUG_template/images/flag-'|add:language.code|add:'.png' as image_static %} + + {% endwith %} + / + {% endfor %} +
    + {% if user.is_active and user.is_staff %} + {% url 'django-admindocs-docroot' as docsroot %} + {% if docsroot %} + {% trans 'Documentation' %} / + {% endif %} + {% endif %} + {% if user.has_usable_password %} + {% trans 'Change password' %} / + {% endif %} + {% trans 'Log out' %} +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/base.html b/webservice/apps/RUG_template/templates/base.html new file mode 100644 index 0000000..2c9d5c3 --- /dev/null +++ b/webservice/apps/RUG_template/templates/base.html @@ -0,0 +1,634 @@ +{% load static %} +{% load i18n %} + + + + + {% block title %}{% trans "Welcome at RUG" %}{% endblock %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% comment %} Requires the Django application django_js_reverse {% endcomment %} + + + {% comment %} Easter egg ;) {% endcomment %} + + + {% comment %} Use for general Django inline formsets {% endcomment %} + + + {% comment %} Toastr {% endcomment %} + + + + {% comment %} MomentJS with locales {% endcomment %} + + + + {% comment %} Add Tablesorter.js {% endcomment %} + + + {% comment %} Basic RUG Template CSS and Javascript {% endcomment %} + + + + {% comment %} Custom CSS and Javascript from the Django Project {% endcomment %} + + + + + + + Skip to ContentSkip to Navigation + +
    +
    +
    + Rijksuniversiteit Groningenfounded in 1614  -  top 100 university + + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + + +
    +
    + + +
    +

    +{% block pagetitle %} -=PageTitle=- {% endblock %} +

    +
    +
    + +
    +{% if messages %} + {% for message in messages %} + + {% endfor %} +{% endif %} +
    +
    +{% block content %} -=PageContent=- {% endblock %} +
    +
    + +
    +
    + +
    + +
    +print +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + + + diff --git a/webservice/apps/RUG_template/templates/index.html b/webservice/apps/RUG_template/templates/index.html new file mode 100644 index 0000000..b5e543e --- /dev/null +++ b/webservice/apps/RUG_template/templates/index.html @@ -0,0 +1,9 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Welcome to the RUG Template page" %}{% endblock %} +{% block pagetitle %}{% trans "Welcome to the RUG Template page" %}{% endblock %} +{% block content %} +

    {% trans "Simple RUG Template" %}

    +

    {% trans "Some more text" %}

    +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/menu.html b/webservice/apps/RUG_template/templates/menu.html new file mode 100644 index 0000000..e3d592a --- /dev/null +++ b/webservice/apps/RUG_template/templates/menu.html @@ -0,0 +1,10 @@ +{% load i18n %} + +
  • + {% trans "Section" %} + +
  • diff --git a/webservice/apps/RUG_template/templates/pager.html b/webservice/apps/RUG_template/templates/pager.html new file mode 100644 index 0000000..b5c35e2 --- /dev/null +++ b/webservice/apps/RUG_template/templates/pager.html @@ -0,0 +1,29 @@ +{% load i18n %} + +{% if page_obj.paginator.num_pages > 1 %} + +{% endif %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/registration/login.html b/webservice/apps/RUG_template/templates/registration/login.html new file mode 100644 index 0000000..8545c9a --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/login.html @@ -0,0 +1,25 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Login" %}{% endblock %} +{% block pagetitle %}{% trans "Login" %}{% endblock %} +{% block content %} +

    + {% trans "Login" %} +
    + {% blocktrans %}You can login here to create your schedules. If you do not have a login, please contact: some_one@rug.nl{% endblocktrans %} +

    +
    + {% csrf_token %} + + + {{ form.as_table }} + + + +
    +
    +
    +{# Assumes you setup the password_reset view in your URLconf #} +

    {% trans "Lost password?" %}

    +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/registration/password_reset_complete.html b/webservice/apps/RUG_template/templates/registration/password_reset_complete.html new file mode 100644 index 0000000..71f51c6 --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/password_reset_complete.html @@ -0,0 +1,10 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Password reset complete" %}{% endblock %} +{% block pagetitle %}{% trans "Password reset complete" %}{% endblock %} +{% block content %} +

    {% trans "Password reset complete" %}

    +{% url 'login' as login_url %} +

    {% blocktrans %}Your new password has been set. You can log in now on the log in page.{% endblocktrans %}

    +{% endblock %} diff --git a/webservice/apps/RUG_template/templates/registration/password_reset_confirm.html b/webservice/apps/RUG_template/templates/registration/password_reset_confirm.html new file mode 100644 index 0000000..e472c5e --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/password_reset_confirm.html @@ -0,0 +1,26 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Set a new password!" %}{% endblock %} +{% block pagetitle %}{% trans "Set a new password!" %}{% endblock %} +{% block content %} +

    {% trans "Set a new password!" %}
    +{% if validlink %} + {% blocktrans %}Here you can set a new password.{% endblocktrans %} +

    +
    + + {% csrf_token %} + {{ form.as_table }} + + + +
    + +
    +
    +{% else %} + {% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}

    +{% endif %} + +{% endblock %} diff --git a/webservice/apps/RUG_template/templates/registration/password_reset_done.html b/webservice/apps/RUG_template/templates/registration/password_reset_done.html new file mode 100644 index 0000000..ffa7012 --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/password_reset_done.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Reset password, email sent" %}{% endblock %} +{% block pagetitle %}{% trans "Reset password, email sent" %}{% endblock %} +{% block content %} +

    +{% trans "Reset password, email sent" %} +
    +
    +{% blocktrans %}We've emailed you instructions for setting your password. You should receive the email shortly!{% endblocktrans %} +

    +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/registration/password_reset_email.html b/webservice/apps/RUG_template/templates/registration/password_reset_email.html new file mode 100644 index 0000000..4106994 --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/password_reset_email.html @@ -0,0 +1,13 @@ +{% load i18n %}{% url 'password_reset_confirm' uidb64=uid token=token as reset_url%} +{% autoescape off %}{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}. + +Please go to the following page and choose a new password: + +{{ protocol}}://{{ domain }}{{ reset_url }} + +Your username, in case you've forgotten: {{ user }} + +Thanks for using our site! + +The {{ site_name }} team{% endblocktrans %} +{% endautoescape %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/registration/password_reset_form.html b/webservice/apps/RUG_template/templates/registration/password_reset_form.html new file mode 100644 index 0000000..362f89b --- /dev/null +++ b/webservice/apps/RUG_template/templates/registration/password_reset_form.html @@ -0,0 +1,21 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Reset password" %}{% endblock %} +{% block pagetitle %}{% trans "Reset password" %}{% endblock %} +{% block content %} +

    +{% trans "Reset password" %} +
    +{% blocktrans %}Here you can request a password reset. Please enter your email address that is used for registration.{% endblocktrans %} +

    +
    + {% csrf_token %} + + {{ form.as_table }} + + + +
    +
    +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/templates/singup.html b/webservice/apps/RUG_template/templates/singup.html new file mode 100644 index 0000000..2e6ff1a --- /dev/null +++ b/webservice/apps/RUG_template/templates/singup.html @@ -0,0 +1,18 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Singup" %}{% endblock %} +{% block pagetitle %}{% trans "Singup" %}{% endblock %} +{% block content %} +

    {% trans "Singup" %}

    + +
    + {% csrf_token %} + + {{ form.as_table }} + + + +
    +
    +{% endblock %} \ No newline at end of file diff --git a/webservice/apps/RUG_template/tests.py b/webservice/apps/RUG_template/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/webservice/apps/RUG_template/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/webservice/apps/RUG_template/urls.py b/webservice/apps/RUG_template/urls.py new file mode 100644 index 0000000..6a0d1d2 --- /dev/null +++ b/webservice/apps/RUG_template/urls.py @@ -0,0 +1,7 @@ +from django.urls import path, include + +from . import views + +urlpatterns = [ + path('', views.index, name='index'), +] \ No newline at end of file diff --git a/webservice/apps/RUG_template/views.py b/webservice/apps/RUG_template/views.py new file mode 100644 index 0000000..8832c3a --- /dev/null +++ b/webservice/apps/RUG_template/views.py @@ -0,0 +1,7 @@ +from django.shortcuts import render + +# Create your views here. +def index(request): + template_name = 'index.html' + + return render(request, template_name, {}) \ No newline at end of file diff --git a/webservice/apps/api/__init__.py b/webservice/apps/api/__init__.py new file mode 100644 index 0000000..b536550 --- /dev/null +++ b/webservice/apps/api/__init__.py @@ -0,0 +1 @@ +default_app_config = 'apps.api.apps.ApiConfig' \ No newline at end of file diff --git a/webservice/apps/api/admin.py b/webservice/apps/api/admin.py new file mode 100644 index 0000000..726805c --- /dev/null +++ b/webservice/apps/api/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from .models import Token + +@admin.register(Token) +class TokenAdmin(admin.ModelAdmin): + list_display = ('key', 'user','is_supertoken', 'last_access') + ordering = ('-last_access', 'user', ) + search_fields = ('key', 'user__username',) + readonly_fields = ('created_at', 'updated_at') diff --git a/webservice/apps/api/apps.py b/webservice/apps/api/apps.py new file mode 100644 index 0000000..8a12abb --- /dev/null +++ b/webservice/apps/api/apps.py @@ -0,0 +1,66 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + +from django.conf import settings + +class ApiConfig(AppConfig): + name = 'apps.api' + label = 'api' + verbose_name = _('API') + verbose_name_plural = _('APIs') + + try: + assert settings.SWAGGER_SETTINGS + except AttributeError: + # We only load this setting, if it is not available in the overall settings.py file + settings.SWAGGER_SETTINGS = { + 'SECURITY_DEFINITIONS': { + 'Hawk': { + 'type': 'apiKey', + 'description': 'HTTP Holder-Of-Key Authentication Scheme, https://github.com/hapijs/hawk, https://hawkrest.readthedocs.io/en/latest/
    Ex header:
    \'Authorization\': \'Hawk mac="F4+S9cu7yZiZEgdtqzMpOOdudvqcV2V2Yzk2WcphECc=", hash="+7fKUX+djeQolvnLTxr0X47e//UHKbkRlajwMw3tx3w=", id="7FI5JET4", ts="1592905433", nonce="DlV-fL"\'', + 'name': 'Authorization', + 'in': 'header' + } + } + } + + try: + assert settings.REST_FRAMEWORK + except AttributeError: + # We only load this setting, if it is not available in the overall settings.py file + # To protect all API views with Hawk by default, put this in your settings: + # https://hawkrest.readthedocs.io/en/latest/usage.html#protecting-api-views-with-hawk + settings.REST_FRAMEWORK = { + + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'apps.api.authentication.APIHawk', + ), + + 'DEFAULT_PERMISSION_CLASSES': ( + 'rest_framework.permissions.IsAuthenticated', + ), + + # 'DEFAULT_AUTHENTICATION_CLASSES': ( + # 'rest_framework.authentication.TokenAuthentication', + # ), + + # 'DEFAULT_PERMISSION_CLASSES': ( + # 'rest_framework.permissions.IsAuthenticated', ), + + # Use Django's standard `django.contrib.auth` permissions, + # or allow read-only access for unauthenticated users. + #'DEFAULT_PERMISSION_CLASSES': [ + # 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' + #], + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', + 'PAGE_SIZE': 10 + } + + try: + assert settings.HAWK_MESSAGE_EXPIRATION + except AttributeError: + # We only load this setting, if it is not available in the overall settings.py file + settings.HAWK_MESSAGE_EXPIRATION = 60 + + def ready(self): + from . import signals \ No newline at end of file diff --git a/webservice/apps/api/authentication.py b/webservice/apps/api/authentication.py new file mode 100644 index 0000000..11f4cac --- /dev/null +++ b/webservice/apps/api/authentication.py @@ -0,0 +1,72 @@ +# import the logging library +import logging +# Get an instance of a logger +logger = logging.getLogger(__name__) + +import django.utils +from rest_framework import exceptions +from hawkrest import HawkAuthentication + +from .models import Token +class APIHawk(HawkAuthentication): + """This is the API authentication that is using the HAWK authentication mechanism. + + This class will implement a custom credentials and user lookups so that we can dynamically add new users and update tokens. + """ + def hawk_credentials_lookup(self, id): + """This method will perform the check if the used token is an existing/known token in the database. This will not lookup a user. Only an existing token. + + Args: + id (string): The token key to lookup in the database for existing token. + + Raises: + exceptions.AuthenticationFailed: If the given token does not exists. + + Returns: + dict: The dictionary holds the token id, the token secret and the used hashing algoritem that is used. + """ + try: + token = Token.objects.get(key=id) + except Token.DoesNotExist: + logger.warning('Requested to validate with invalid/non existing token: {}'.format(id)) + raise exceptions.AuthenticationFailed('No such token: {}'.format(id)) + + return { + 'id' : id, + 'key' : token.secret, + 'algorithm' : 'sha256' + } + + def hawk_user_lookup(self, request, credentials): + """Return the user account that is connected to the used token. + + Args: + request ([type]): The incoming HTTP/API request + credentials (dict): The credentials from ~hawk_credentials_lookup + + Raises: + exceptions.AuthenticationFailed: If the given token does not exists to an existing user + + Returns: + tuple: Returns a tuple holding the user as first item + """ + user = None + try: + user = Token.objects.get(key=credentials['id']).user + except Token.DoesNotExist: + logger.warning('Requested to validate non existing user: {}'.format(id)) + raise exceptions.AuthenticationFailed('No user for token: {}'.format(credentials['id'])) + + # Update the date time stamp to now for last access data + user.token.last_access = django.utils.timezone.now() + user.token.save() + + return (user,None) + + def __repr__(self): + """Authentication identifier. + + Returns: + string: Returns the name of the used authentication mechanism. + """ + return 'Hawk authenticator' \ No newline at end of file diff --git a/webservice/apps/api/locale/en/LC_MESSAGES/django.mo b/webservice/apps/api/locale/en/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..71cbdf3e9d8d54be31066ec4ad8628bc2c1f2845 GIT binary patch literal 380 zcmYL@K~KUk7=|%=+R?Lz&%}d9i{c3jGZa>EvE7z2Nc2{r&Y96JZ6W$Y{CoZuJ5A(G zp7i_Dx9RhJeDu}vIq;l#&OC>nD^HugXY4QU{MmN?lNtRkR}RH%w3NnHT4Bh@vF%H^(V-=Ii1iQ$Qo9Pt!I1Rhe%oml#`f^NEGFCKEL->Rc=KoQ6a?!10%_7(V7ey8`V`;n{war z20Z3;uifk31QV^CRQ|iq#``$=;jWunRB8aLH({)F;i8zL{=V00y-I_qTIqGAN(}v% i$^}`yHKImSZ8jEzYJOK6-VWez49^vuhS0kh1f3tbb!oc* literal 0 HcmV?d00001 diff --git a/webservice/apps/api/locale/en/LC_MESSAGES/django.po b/webservice/apps/api/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..a227bee --- /dev/null +++ b/webservice/apps/api/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,67 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-07-30 15:42+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: apps/api/apps.py:9 +msgid "API" +msgstr "" + +#: apps/api/apps.py:10 +msgid "APIs" +msgstr "" + +#: apps/api/models.py:28 +msgid "token" +msgstr "" + +#: apps/api/models.py:29 +msgid "tokens" +msgstr "" + +#: apps/api/models.py:31 +msgid "Select the user for this token" +msgstr "" + +#: apps/api/models.py:32 +msgid "Key" +msgstr "" + +#: apps/api/models.py:32 +msgid "The key for this token. This is used for Hawk verification." +msgstr "" + +#: apps/api/models.py:33 +msgid "Secret" +msgstr "" + +#: apps/api/models.py:33 +msgid "The secret for this token. This is used for Hawk signing." +msgstr "" + +#: apps/api/models.py:34 +msgid "Last access" +msgstr "" + +#: apps/api/models.py:34 +msgid "The date and time when this token is last used." +msgstr "" + +#: apps/api/models.py:44 +msgid "Super token" +msgstr "" diff --git a/webservice/apps/api/locale/nl/LC_MESSAGES/django.mo b/webservice/apps/api/locale/nl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..64148064b81e397984b8a569fb33a68d9f4fa155 GIT binary patch literal 441 zcmYL_OHRWu5QYPkO_r=#m>mdBNF!RRlptO$Dr!Yk1;i4!8C+Mvj%)|PLAVDC&cj(4 zQ$a`mG*4@O`+KML5s+;WyTmcEO^gX|PlWGrqD3Gv*a(6pd0+pe*w??v)A_eeihMt~ z$VVO<#3SrR8P#2rXZ zSi74hokPmwaLlcP!f<6P?zBnSt+tDXvuQJvN-WsvG7^zlCFiCQk*dzWWL%XY&O&7F~8<457E4^Kzciz(CD) zNitH_n@JbuRbzMsLv3Cxt*U=hn+Nx8;SI+jFn)D73) F`2$3XbJzd? literal 0 HcmV?d00001 diff --git a/webservice/apps/api/locale/nl/LC_MESSAGES/django.po b/webservice/apps/api/locale/nl/LC_MESSAGES/django.po new file mode 100644 index 0000000..071a7b3 --- /dev/null +++ b/webservice/apps/api/locale/nl/LC_MESSAGES/django.po @@ -0,0 +1,67 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-07-30 15:42+0200\n" +"PO-Revision-Date: 2020-05-27 16:25+0200\n" +"Last-Translator: Joshua Rubingh \n" +"Language-Team: \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.6\n" + +#: apps/api/apps.py:9 +msgid "API" +msgstr "API" + +#: apps/api/apps.py:10 +msgid "APIs" +msgstr "APIs" + +#: apps/api/models.py:28 +msgid "token" +msgstr "" + +#: apps/api/models.py:29 +msgid "tokens" +msgstr "" + +#: apps/api/models.py:31 +msgid "Select the user for this token" +msgstr "" + +#: apps/api/models.py:32 +msgid "Key" +msgstr "" + +#: apps/api/models.py:32 +msgid "The key for this token. This is used for Hawk verification." +msgstr "" + +#: apps/api/models.py:33 +msgid "Secret" +msgstr "" + +#: apps/api/models.py:33 +msgid "The secret for this token. This is used for Hawk signing." +msgstr "" + +#: apps/api/models.py:34 +msgid "Last access" +msgstr "" + +#: apps/api/models.py:34 +msgid "The date and time when this token is last used." +msgstr "" + +#: apps/api/models.py:44 +msgid "Super token" +msgstr "" diff --git a/webservice/apps/api/migrations/0001_initial.py b/webservice/apps/api/migrations/0001_initial.py new file mode 100644 index 0000000..fd23d06 --- /dev/null +++ b/webservice/apps/api/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# Generated by Django 3.0.8 on 2020-07-30 14:15 + +import apps.api.models +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django_cryptography.fields + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Token', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True, help_text='The date and time this model has been created', verbose_name='Date created')), + ('updated_at', models.DateTimeField(auto_now=True, help_text='The date and time this model has been updated', verbose_name='Date updated')), + ('key', models.CharField(default=apps.api.models.get_random_key, help_text='The key for this token. This is used for Hawk verification.', max_length=16, unique=True, verbose_name='Key')), + ('secret', django_cryptography.fields.encrypt(models.CharField(default=apps.api.models.get_random_secret, help_text='The secret for this token. This is used for Hawk signing.', max_length=64, verbose_name='Secret'))), + ('last_access', models.DateTimeField(auto_now_add=True, help_text='The date and time when this token is last used.', verbose_name='Last access')), + ('user', models.OneToOneField(help_text='Select the user for this token', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'token', + 'verbose_name_plural': 'tokens', + }, + ), + ] diff --git a/webservice/apps/api/migrations/__init__.py b/webservice/apps/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webservice/apps/api/models.py b/webservice/apps/api/models.py new file mode 100644 index 0000000..3603aef --- /dev/null +++ b/webservice/apps/api/models.py @@ -0,0 +1,70 @@ +from django.contrib.auth.models import User +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from django_cryptography.fields import encrypt + +from lib.utils.general import get_random_string +from lib.models.base import MetaDataModel + + +def get_random_key(): + return get_random_string(8) + +def get_random_secret(): + return get_random_string(32) + +class TokenManager(models.Manager): + """ + Custom queryset which will prefetch related user table data when requesting a token from the database as the user is mostly needed every time the token is requested. + """ + + def get_queryset(self): + return super(TokenManager, self).get_queryset().select_related('user') + +class Token(MetaDataModel): + """Token model that holds all the tokens that are used for the API authentication. + + A new token is generated every time when a new user is created. So there is no need for manual token creating. This is done through a signal :attr:`~apps.api.signals.create_user_token` + + Attributes + ---------- + user : :class:`~django.contrib.auth.models.User` + The user to which this token belongs too + key : str + The key value that is used for token lookups + secret : str + The secret that is used for encrypting/signing the API messages + last_access : datetime + The date and time when the token is last used (logged in) + """ + + class Meta: + verbose_name = _('token') + verbose_name_plural = _('tokens') + + user = models.OneToOneField(User, on_delete=models.CASCADE, help_text=_('Select the user for this token')) + key = models.CharField(_('Key') , unique=True, default=get_random_key, max_length=16, help_text=_('The key for this token. This is used for Hawk verification.')) + secret = encrypt(models.CharField(_('Secret') ,max_length=64, default=get_random_secret, help_text=_('The secret for this token. This is used for Hawk signing.'))) + last_access = models.DateTimeField(_('Last access'),auto_now_add=True, help_text=_('The date and time when this token is last used.')) + + # Custom manager that will retrieve the related user table as well. + objects = TokenManager() + + def is_supertoken(self): + """Boolean check if the token is belonging to a user with super user rights. Then this token is a super token. + + Returns: + bool: Returns true when the token belongs to a super user. + """ + # TODO: Is it allowed to be a super user and researcher? Could give conflict of interests. With the API token you can read other researchers data... + return self.user.is_superuser == True + + is_supertoken.boolean = True + is_supertoken.short_description = _('Super token') + + def __str__(self): + """ + Print the full name of the researcher based on the first and last name fields of the User model. + """ + return '{} ({})'.format(self.key,self.user.get_full_name()) \ No newline at end of file diff --git a/webservice/apps/api/signals.py b/webservice/apps/api/signals.py new file mode 100644 index 0000000..e4e4c8a --- /dev/null +++ b/webservice/apps/api/signals.py @@ -0,0 +1,24 @@ +from django.conf import settings +from django.db.models.signals import post_save +from django.dispatch import receiver + +from .models import Token + +@receiver(post_save, sender=settings.AUTH_USER_MODEL) +def create_user_token(sender, instance=None, created=False, **kwargs): + """ + When a new user is created, this signal will also create a new API token for this user. So every user will have an API token. + + Arguments + ---------- + sender : sender + The model that has triggered the signal + + instance: :attr:`~django.contrib.auth.models.User` + The newly created user model data + + created : boolean + Wether the object was created (True) or updated (False). + """ + if created: + Token.objects.create(user=instance) diff --git a/webservice/apps/api/tests.py b/webservice/apps/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/webservice/apps/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/webservice/apps/api/urls.py b/webservice/apps/api/urls.py new file mode 100644 index 0000000..0a40e1e --- /dev/null +++ b/webservice/apps/api/urls.py @@ -0,0 +1,71 @@ +from django.urls import path, re_path, include + +from rest_framework import permissions, routers + +from drf_yasg2.views import get_schema_view +from drf_yasg2 import openapi + +from . import views + +from apps.dropoff.api.views import DatadropViewSet +from apps.invitation.api.views import InvitationViewSet +from apps.researcher.api.views import ResearcherViewSet +from apps.storage.api.views import StorageEngineViewSet, StorageLocationViewSet +from apps.study.api.views import StudyViewSet +from apps.virtual_machine.api.views import (VirtualMachineViewSet, + VirtualMachineOperatingSystemViewSet, + VirtualMachineProfileViewSet, + VirtualMachineMemoryViewSet, + VirtualMachineNetworkViewSet, + VirtualMachineStorageViewSet, + VirtualMachineGPUViewSet) + +schema_view = get_schema_view( + openapi.Info( + title="Virtual Research Environment API", + default_version='v1', + description="Here you can see a list of API endpoints and actions that are available to communicate with the VRE API", + terms_of_service="https://www.rug.nl", + contact=openapi.Contact(email="vre_team@rug.nl"), + license=openapi.License(name="MIT License"), + ), + public=True, + permission_classes=(permissions.AllowAny,), +) + +api_router_v1 = routers.DefaultRouter() + +api_router_v1.register(r'researchers', ResearcherViewSet) + +api_router_v1.register(r'studies', StudyViewSet) + +api_router_v1.register(r'dropoffs', DatadropViewSet) + +api_router_v1.register(r'invitations', InvitationViewSet) + +api_router_v1.register(r'storageengines', StorageEngineViewSet) +api_router_v1.register(r'storagelocations', StorageLocationViewSet) + +# Order is important for virtual machines. Longest match first +api_router_v1.register(r'virtualmachines/profiles', VirtualMachineProfileViewSet) +api_router_v1.register(r'virtualmachines/storage', VirtualMachineStorageViewSet) +api_router_v1.register(r'virtualmachines/memory', VirtualMachineMemoryViewSet) +api_router_v1.register(r'virtualmachines/network', VirtualMachineNetworkViewSet) +api_router_v1.register(r'virtualmachines/gpu', VirtualMachineGPUViewSet) +api_router_v1.register(r'virtualmachines/os', VirtualMachineOperatingSystemViewSet) +api_router_v1.register(r'virtualmachines', VirtualMachineViewSet) + +# Main namespace for the API urls +app_name = 'api' +urlpatterns = [ + re_path(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), + path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), + path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), + + # Extra /api/info path for checking if the Hawk authentication is working. + # Also this will give the full url to the OpenAPI documentation + path('info/', views.Info.as_view(), name='info'), + + # Add extra namespace for versioning the API + path('v1/', include((api_router_v1.urls,'api'),namespace='v1')), +] \ No newline at end of file diff --git a/webservice/apps/api/views.py b/webservice/apps/api/views.py new file mode 100644 index 0000000..0049650 --- /dev/null +++ b/webservice/apps/api/views.py @@ -0,0 +1,52 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.decorators import schema + +from django.urls import reverse + +from lib.utils.general import get_ip_address + +@schema(None) +class Info(APIView): + """ + Show some API information. Also this can be used to check if the Hawk credentials are working. + + Make sure your request does contain the header 'Content-Type': 'application/json' + """ + + def get(self, request, format=None): + """ + Default API get action will return the following information in a dict: + + - Connected user + - Used authentication scheme + - The remote IP of the connection + - The used content type + - The full url to the API documentation (OpenAPI) + - If a super token is used + """ + + data = { + 'type' : 'anonymous', + 'auth' : 'none', + 'remote_ip' : get_ip_address(request), + 'content_type' : request.content_type, + 'openapi' : request.build_absolute_uri(reverse('api:schema-redoc')), + } + + if request.user.is_authenticated: + + data['user'] = request.user.username + data['type'] = 'authenticated' + data['auth'] = str(request.successful_authenticator) + + if request.user.token.is_supertoken: + data['type'] = 'supertoken' + else: + try: + assert request.user.researcher + data['type'] = 'researcher' + except AttributeError: + pass + + return Response(data) \ No newline at end of file diff --git a/webservice/apps/synthea/__init__.py b/webservice/apps/synthea/__init__.py new file mode 100644 index 0000000..8ba84a1 --- /dev/null +++ b/webservice/apps/synthea/__init__.py @@ -0,0 +1 @@ +default_app_config = 'apps.synthea.apps.SyntheaConfig' \ No newline at end of file diff --git a/webservice/apps/synthea/admin.py b/webservice/apps/synthea/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/webservice/apps/synthea/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/webservice/apps/synthea/apps.py b/webservice/apps/synthea/apps.py new file mode 100644 index 0000000..4ea0616 --- /dev/null +++ b/webservice/apps/synthea/apps.py @@ -0,0 +1,10 @@ +from django.apps import AppConfig +from django.utils.translation import ugettext_lazy as _ + +from django.conf import settings + +class SyntheaConfig(AppConfig): + name = 'apps.synthea' + label = 'synthea' + verbose_name = _('Synthea') + verbose_name_plural = _('Synthea') \ No newline at end of file diff --git a/webservice/apps/synthea/forms.py b/webservice/apps/synthea/forms.py new file mode 100644 index 0000000..01fbc7c --- /dev/null +++ b/webservice/apps/synthea/forms.py @@ -0,0 +1,27 @@ +from django.forms import ModelForm +from django import forms + +from apps.synthea.models import Synthea + +from .lib.utils import available_states, available_modules + +class SyntheaForm(ModelForm): + + class Meta: + model = Synthea + fields = ['state', 'population', 'gender', 'age', 'module'] + + # This is loaded only once during startup. So changing the state data will not be picked up after a restart + state_options = [('','Any')] + for item in available_states(): + state_options.append((item,item)) + + module_options = [('','Any')] + for item in available_modules(): + module_options.append((item['module'],item['name'])) + + widgets = { + 'state': forms.Select(choices=state_options), + 'gender': forms.Select(choices=[('','Any'),('m','Male'),('f','Female')]), + 'module': forms.Select(choices=module_options) + } \ No newline at end of file diff --git a/webservice/apps/synthea/lib/utils.py b/webservice/apps/synthea/lib/utils.py new file mode 100644 index 0000000..ab0d59e --- /dev/null +++ b/webservice/apps/synthea/lib/utils.py @@ -0,0 +1,83 @@ +from pathlib import Path +import pandas as pd +import shlex +import subprocess +from zipfile import ZipFile +import json + +def available_states(): + #TODO: Make a setting for this path + location = Path('/opt/development/synthea_webservice/synthea/src/main/resources/geography/') + + df = pd.read_csv(location / 'timezones.csv', index_col=False) + # The state information is expected in the first column + states = df[df.columns[0]].to_list() + states.sort() + return states + +def available_modules(): + #TODO: Make a setting for this path + location = Path('/opt/development/synthea_webservice/synthea/src/main/resources/modules/') + + # Assumption here: A folder is a single module. And all .json in the main modules folder is a module. + modules = [] + for module in location.iterdir(): + if module.is_file() and module.suffix == '.json': + data = json.loads(module.read_text()) + modules.append({'module' : module.name.replace('.json',''), 'name' : data['name']}) + + modules = sorted(modules, key=lambda k: k['name'].lower()) + return modules + +def run_synthea(state = None, population = None, gender = None, age = None, module = None): + # TODO: Make synthea setting(s) + location = '/opt/development/synthea_webservice/synthea/' + synthea_cmd = ['/opt/development/synthea_webservice/synthea/run_synthea'] + zip_file = 'Synthea_' + zip_export = location + + if population: + synthea_cmd.append('-p') + synthea_cmd.append(str(population)) + zip_file += f'population_{population}_' + + if gender: + synthea_cmd.append('-g') + synthea_cmd.append(gender.upper()) + zip_file += f'gender_{gender}_' + + if age: + synthea_cmd.append('-a') + synthea_cmd.append(age) + zip_file += f'age_{age}_' + + if module: + synthea_cmd.append('-m') + synthea_cmd.append(module) + zip_file += f'module_{module}_' + + if state: + synthea_cmd.append(state) + zip_file += f'state_{state}' + + process_ok = False + log = '' + with subprocess.Popen(synthea_cmd,cwd=location, stdout=subprocess.PIPE,stderr=subprocess.PIPE) as process: + for line in process.stdout: + line = line.decode('utf8') + log += line + if not process_ok: + process_ok = line.find('BUILD SUCCESSFUL') >= 0 + + if process_ok: + with ZipFile(f'{zip_export}/{zip_file}.zip', 'w') as export: + for file in Path(location + 'output/fhir_stu3').iterdir(): + export.write(file,file.name) + + return Path(f'{zip_export}/{zip_file}.zip') + else: + raise Exception(log) + + + + diff --git a/webservice/apps/synthea/migrations/0001_initial.py b/webservice/apps/synthea/migrations/0001_initial.py new file mode 100644 index 0000000..3221990 --- /dev/null +++ b/webservice/apps/synthea/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.3 on 2020-11-13 09:36 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Synthea', + fields=[ + ('created_at', models.DateTimeField(auto_now_add=True, help_text='The date and time this model has been created', verbose_name='Date created')), + ('updated_at', models.DateTimeField(auto_now=True, help_text='The date and time this model has been updated', verbose_name='Date updated')), + ('id', models.UUIDField(default=uuid.uuid4, editable=False, help_text='A unique id', primary_key=True, serialize=False, unique=True, verbose_name='ID')), + ('state', models.CharField(help_text='The state for which synthea generate data.', max_length=200, verbose_name='Stage')), + ('population', models.PositiveSmallIntegerField(default=50, help_text='The size of the population', verbose_name='Population')), + ('gender', models.CharField(help_text='Select the gender type', max_length=1, verbose_name='Gender')), + ('age', models.CharField(help_text='Select the age range', max_length=10, verbose_name='Age range')), + ('module', models.CharField(help_text='Select the module', max_length=50, verbose_name='Mopdule')), + ], + options={ + 'verbose_name': 'token', + 'verbose_name_plural': 'tokens', + }, + ), + ] diff --git a/webservice/apps/synthea/migrations/__init__.py b/webservice/apps/synthea/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webservice/apps/synthea/models.py b/webservice/apps/synthea/models.py new file mode 100644 index 0000000..8892f2d --- /dev/null +++ b/webservice/apps/synthea/models.py @@ -0,0 +1,24 @@ +from django.contrib.auth.models import User +from django.db import models +from django.utils.translation import gettext_lazy as _ + +from django_cryptography.fields import encrypt + +from lib.utils.general import get_random_string +from lib.models.base import MetaDataModel + +import uuid + +# Create your models here. +class Synthea(MetaDataModel): + + class Meta: + verbose_name = _('token') + verbose_name_plural = _('tokens') + + id = models.UUIDField(_('ID'), primary_key=True, unique=True, default=uuid.uuid4, editable=False, help_text=_('A unique id')) + state = models.CharField(_('State'), max_length=200, help_text=_('The state for which synthea generate data.')) + population = models.PositiveSmallIntegerField(_('Population'), blank=True, default=50, help_text=_('The size of the population')) + gender = models.CharField(_('Gender'), blank=True,max_length=1, help_text=_('Select the gender type')) + age = models.CharField(_('Age range'), blank=True,max_length=10, help_text=_('Select the age range')) + module = models.CharField(_('Module'),blank=True, max_length=50, help_text=_('Select the module')) diff --git a/webservice/apps/synthea/templates/synthea/generator_form.html b/webservice/apps/synthea/templates/synthea/generator_form.html new file mode 100644 index 0000000..3aafae7 --- /dev/null +++ b/webservice/apps/synthea/templates/synthea/generator_form.html @@ -0,0 +1,21 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "Generate a new Synthea data set" %}{% endblock %} +{% block pagetitle %}{% trans "Generate a new Synthea data set" %}{% endblock %} + +{% block menu %} + {% include 'synthea/menu.html' %} +{% endblock %} + +{% block content %} +

    Synthea generartor

    +

    Enter the form fields and press submit. U vraagt, wij draaien ;)

    +
    + {% csrf_token %} + + {{ form.as_table }} +
    + +
    +{% endblock %} diff --git a/webservice/apps/synthea/templates/synthea/index.html b/webservice/apps/synthea/templates/synthea/index.html new file mode 100644 index 0000000..5e83ce1 --- /dev/null +++ b/webservice/apps/synthea/templates/synthea/index.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block title %}{% trans "dHealth Synthea" %}{% endblock %} +{% block pagetitle %}{% trans "dHealth Synthea" %}{% endblock %} + +{% block menu %} + {% include 'synthea/menu.html' %} +{% endblock %} + +{% block content %} +

    dHealt Nederland

    +

    Onder leiding van UMCG

    +{% endblock %} diff --git a/webservice/apps/synthea/templates/synthea/menu.html b/webservice/apps/synthea/templates/synthea/menu.html new file mode 100644 index 0000000..f2145a9 --- /dev/null +++ b/webservice/apps/synthea/templates/synthea/menu.html @@ -0,0 +1,17 @@ +{% load i18n %} +
  • + {% trans "Menu" %} + +
  • \ No newline at end of file diff --git a/webservice/apps/synthea/tests.py b/webservice/apps/synthea/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/webservice/apps/synthea/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/webservice/apps/synthea/urls.py b/webservice/apps/synthea/urls.py new file mode 100644 index 0000000..e8ed444 --- /dev/null +++ b/webservice/apps/synthea/urls.py @@ -0,0 +1,9 @@ +from django.urls import path, include + +from . import views + +urlpatterns = [ + path('', views.index, name='index'), + path('api/', views.index, name='api_info'), + path('generate/', views.show_synthea_form, name='generator_form'), +] \ No newline at end of file diff --git a/webservice/apps/synthea/views.py b/webservice/apps/synthea/views.py new file mode 100644 index 0000000..a43e0bc --- /dev/null +++ b/webservice/apps/synthea/views.py @@ -0,0 +1,49 @@ +from django.shortcuts import render +from django.http import HttpResponse +from apps.synthea.forms import SyntheaForm + +from .lib.utils import run_synthea + +import mimetypes +# Create your views here. + +def index(request): + template_name = 'synthea/index.html' + return render(request,template_name,{}) + +def show_synthea_form(request): + template_name = 'synthea/generator_form.html' + + # if this is a POST request we need to process the form data + if request.method == 'POST': + # create a form instance and populate it with data from the request: + form = SyntheaForm(request.POST) + # check whether it's valid: + if form.is_valid(): + # process the data in form.cleaned_data as required + + try: + zipfile = run_synthea( + form.cleaned_data['state'], + form.cleaned_data['population'], + form.cleaned_data['gender'], + form.cleaned_data['age'], + form.cleaned_data['module'] + ) + + mime_type, _ = mimetypes.guess_type(zipfile) + response = HttpResponse(zipfile.open('rb'), content_type=mime_type) + response['Content-Disposition'] = f'attachment; filename={zipfile.name}' + + return response + + except Exception as ex: + print(ex) + + # if a GET (or any other method) we'll create a blank form + else: + form = SyntheaForm() + + return render(request,template_name,{ + 'form':form + }) \ No newline at end of file diff --git a/webservice/db.sqlite3 b/webservice/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..8e79434601899f8f4a66b8ffcdfe1cc762bbeab4 GIT binary patch literal 151552 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 literal 0 HcmV?d00001 diff --git a/webservice/lib/api/base.py b/webservice/lib/api/base.py new file mode 100644 index 0000000..755ad52 --- /dev/null +++ b/webservice/lib/api/base.py @@ -0,0 +1,45 @@ +from rest_framework import viewsets, permissions, serializers +from rest_framework.permissions import BasePermission + +class IsOwner(BasePermission): + def has_object_permission (self, request, view, obj ): + """Return 'True' if permission is granted, 'False' otherwise.""" + # TODO: If this is the 'way to go', we should consider adding the researcher reference to all models and save actions + return obj.researcher == request.user.researcher or obj.study.researcher == request.user.researcher + +class BaseReadOnlyViewSet(viewsets.ReadOnlyModelViewSet): + permission_classes = [permissions.IsAuthenticated, IsOwner] + + # TODO: If this is the 'way to go', we should consider adding the researcher reference to all models and save actions + def get_queryset(self): + try: + qs = self.queryset.filter(researcher = self.request.user.researcher) + except: + qs = self.queryset.filter(study__researcher = self.request.user.researcher) + + return qs + +class BaseViewSet(viewsets.ModelViewSet): + permission_classes = [permissions.IsAuthenticated, IsOwner] + + # TODO: If this is the 'way to go', we should consider adding the researcher reference to all models and save actions + def get_queryset(self): + try: + qs = self.queryset.filter(researcher = self.request.user.researcher) + except: + qs = self.queryset.filter(study__researcher = self.request.user.researcher) + + return qs + +class BaseHyperlinkedModelSerializer(serializers.HyperlinkedModelSerializer): + # This ID field is handy to have.... Due to HyperlinkedModelSerializer we do not have this field by default + id = serializers.ReadOnlyField() + + # Only show the researcher full name + researcher = serializers.StringRelatedField() + + # Only show link to full researcher data + #researcher = serializers.HyperlinkedRelatedField(view_name= 'api:v1:researcher-detail', read_only=True) + + # Show the full researcher information + #researcher = ResearcherSerializer(read_only=True) diff --git a/webservice/lib/api/client.py b/webservice/lib/api/client.py new file mode 100644 index 0000000..1049ce7 --- /dev/null +++ b/webservice/lib/api/client.py @@ -0,0 +1,145 @@ +import requests +from requests_hawk import HawkAuth +from datetime import datetime + +class VRE_API_Exception(BaseException): + def __init__(self, message, error): + # Call the base class constructor with the parameters it needs + super().__init__(message) + # Now for your custom code... + self.error = error + + def __repr__(self): + return '{} ({})'.format(self.message, self.error) + +class VRE_API_Exception_Factory(VRE_API_Exception): + + def __new__(self, message, error_code): + if error_code == 400: + return VRE_API_400(message) + elif error_code == 403: + return VRE_API_403(message) + elif error_code == 404: + return VRE_API_404(message) + +class VRE_API_400(VRE_API_Exception): + def __init__(self, message): + # Call the base class constructor with the parameters it needs + super().__init__(message, 403) + +class VRE_API_403(VRE_API_Exception): + def __init__(self, message): + # Call the base class constructor with the parameters it needs + super().__init__(message, 403) + +class VRE_API_404(VRE_API_Exception): + def __init__(self, message): + # Call the base class constructor with the parameters it needs + super().__init__(message, 404) + +class VRE_API_Client(): + + DATE_TIME_FIELDS = 'created_at,updated_at,mail_sent'.split(',') + + HEADERS = { + 'Content-Type': 'application/json', + 'cache-control': 'no-cache' + } + + def __init__(self, host, url = None, token = None, secret = None): + self.host = host + self.url = url + self.token = token + self.secret = secret + + self.data = {} + self.authentication = HawkAuth(id=self.token , key=self.secret) + + def __get_full_url(self): + return '{}{}'.format(self.host, self.url) + + def __parse_date_time_fields(self, data): + for item in data: + # TODO: Should provide better solution for this try/catch. For now it works + try: + if isinstance(item,list) or isinstance(item,dict): + self.__parse_date_time_fields(item) + + elif isinstance(data[item],list) or isinstance(data[item],dict): + self.__parse_date_time_fields(data[item]) + + elif item in self.DATE_TIME_FIELDS and isinstance(data[item],str): + try: + data[item] = datetime.strptime(data[item],'%Y-%m-%dT%H:%M:%S.%fZ') + except Exception: + data[item] = datetime.strptime(data[item][::-1].replace(':','',1)[::-1].replace(' ','T'),'%Y-%m-%dT%H:%M:%S.%f%z') + except Exception: + pass + + def __parse_data(self, start = None): + if len(self.DATE_TIME_FIELDS) > 0: + self.__parse_date_time_fields(self.data) + + def set_url(self, url): + self.url = url + + def set_token(self, token): + self.token = token + self.authentication = HawkAuth(id=self.token , key=self.secret) + + def set_secret(self, secret): + self.secret = secret + self.authentication = HawkAuth(id=self.token , key=self.secret) + + def get_data(self): + result = requests.get(self.__get_full_url(), auth=self.authentication, headers=self.HEADERS) + self.data['status_code'] = result.status_code + + if result.status_code in [200,201]: + self.data = result.json() + self.__parse_data() + else: + print(result.json()) + raise VRE_API_Exception_Factory('Error with url {}.'.format(self.url),result.status_code) + + return self.data + + def post_data(self, payload): + result = requests.post(self.__get_full_url(), json=payload, auth=self.authentication, headers=self.HEADERS) + self.data['status_code'] = result.status_code + + if result.status_code in [200,201]: + self.data = result.json() + self.__parse_data() + else: + #print(result.content) + + #print(result.text) + + raise VRE_API_Exception_Factory('Error with url {}.'.format(self.url),result.status_code) + + return self.data + + def put_data(self, payload): + result = requests.put(self.__get_full_url(), json=payload, auth=self.authentication, headers=self.HEADERS) + self.data['status_code'] = result.status_code + + if result.status_code in [200,201]: + self.data = result.json() + self.__parse_data() + else: + print(result.json()) + raise VRE_API_Exception_Factory('Error with url {}.'.format(self.url),result.status_code) + + return self.data + + def delete_data(self): + try: + # Django HAWK has issues with a delete action. It needs/wants a content-type header, but there is no content..... + # https://github.com/kumar303/hawkrest/issues/46 + result = requests.delete(self.__get_full_url(), auth=self.authentication, headers=self.HEADERS) + return result.status_code in [200,201,204] + except Exception: + raise VRE_API_Exception_Factory('Error with url {}.'.format(self.url),result.status_code) + + return False \ No newline at end of file diff --git a/webservice/lib/models/base.py b/webservice/lib/models/base.py new file mode 100644 index 0000000..8a863c4 --- /dev/null +++ b/webservice/lib/models/base.py @@ -0,0 +1,20 @@ + +from django.db import models +from django.utils.translation import gettext_lazy as _ + +class MetaDataModel(models.Model): + """ + This is an abstract Django model with some general meta fields that can be used for other models. + + Attributes + ---------- + created_at : datetime + The date and time when the model has been created. This will be automatically set once during creating. + updated_at : datetime + The date and time when the model has been updated. This will be automatically updated when the model is updated. + """ + created_at = models.DateTimeField(_('Date created'),auto_now_add=True, help_text=_('The date and time this model has been created')) + updated_at = models.DateTimeField(_('Date updated'),auto_now=True, help_text=_('The date and time this model has been updated')) + + class Meta: + abstract = True \ No newline at end of file diff --git a/webservice/lib/utils/emails.py b/webservice/lib/utils/emails.py new file mode 100644 index 0000000..ac545e3 --- /dev/null +++ b/webservice/lib/utils/emails.py @@ -0,0 +1,84 @@ +import os.path +import re +import mimetypes + +from email.mime.base import MIMEBase +from django.core.mail import EmailMultiAlternatives, SafeMIMEMultipart +from django.conf import settings + +# Source: https://djangosnippets.org/snippets/2215/ +class EmailMultiRelated(EmailMultiAlternatives): + """ + A version of EmailMessage that makes it easy to send multipart/related + messages. For example, including text and HTML versions with inline images. + """ + related_subtype = 'related' + + def __init__(self, subject='', body='', from_email=None, to=None, bcc=None, + connection=None, attachments=None, headers=None, alternatives=None): + # self.related_ids = [] + self.related_attachments = [] + super(EmailMultiRelated, self).__init__(subject, body, from_email, to, bcc, connection, attachments, headers, alternatives) + + def attach_related(self, filename=None, content=None, mimetype=None): + """ + Attaches a file with the given filename and content. The filename can + be omitted and the mimetype is guessed, if not provided. + + If the first parameter is a MIMEBase subclass it is inserted directly + into the resulting message attachments. + """ + if isinstance(filename, MIMEBase): + assert content == mimetype == None + self.related_attachments.append(filename) + else: + assert content is not None + self.related_attachments.append((filename, content, mimetype)) + + def attach_related_file(self, path, mimetype=None): + """Attaches a file from the filesystem.""" + filename = os.path.basename(path) + content = open(path, 'rb').read() + if mimetype is None: + mimetypes.init() + mimetype = mimetypes.guess_type(filename)[0] + self.attach_related(filename, content, mimetype) + + def _create_message(self, msg): + return self._create_attachments(self._create_related_attachments(self._create_alternatives(msg))) + + def _create_alternatives(self, msg): + for i, (content, mimetype) in enumerate(self.alternatives): + if mimetype == 'text/html': + for filename, _, _ in self.related_attachments: + content = re.sub(r'(?' % filename) + return attachment \ No newline at end of file diff --git a/webservice/lib/utils/general.py b/webservice/lib/utils/general.py new file mode 100644 index 0000000..05cce2c --- /dev/null +++ b/webservice/lib/utils/general.py @@ -0,0 +1,26 @@ +import re +import random +import string + +def remove_html_tags(text): + """Remove html tags from a string""" + clean = re.compile('<.*?>') + return re.sub(clean, '', text) + +def get_random_int_value(length = 6): + return ''.join(list(map(lambda x: str(random.randint(1,9)), list(range(length))))) + +def get_random_string(length = 8): + return ''.join(random.choices(string.ascii_uppercase + string.digits + string.ascii_lowercase, k=length)) + +def generate_encryption_key(length = 32): + return get_random_string(length) + +def get_ip_address(request): + """ use requestobject to fetch client machine's IP Address """ + x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', None) + if x_forwarded_for: + ip = x_forwarded_for.split(',')[0] + else: + ip = request.META.get('REMOTE_ADDR') ### Real IP address of client Machine + return ip \ No newline at end of file diff --git a/webservice/manage.py b/webservice/manage.py new file mode 100755 index 0000000..61ddd5d --- /dev/null +++ b/webservice/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webservice.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/webservice/static/images/.gitignore b/webservice/static/images/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/webservice/static/javascript/javascript.js b/webservice/static/javascript/javascript.js new file mode 100644 index 0000000..c3aadf9 --- /dev/null +++ b/webservice/static/javascript/javascript.js @@ -0,0 +1 @@ +/* Dummy javascript file */ \ No newline at end of file diff --git a/webservice/static/style/style.css b/webservice/static/style/style.css new file mode 100644 index 0000000..236c4b8 --- /dev/null +++ b/webservice/static/style/style.css @@ -0,0 +1 @@ +/* Dummy style sheet */ \ No newline at end of file diff --git a/webservice/webservice/.env b/webservice/webservice/.env new file mode 100644 index 0000000..c1d7308 --- /dev/null +++ b/webservice/webservice/.env @@ -0,0 +1,41 @@ +# A uniquely secret key +SECRET_KEY=@wb=#(f4vc0l(e!5*eo+a@flnxb2@!l9!=c6w=4b+x$=!8&vy%' + +# Disable debug in production +DEBUG=True + +# Allowed hosts that Django does server. Take care when NGINX is proxying infront of Django +ALLOWED_HOSTS=127.0.0.1,localhost + +# All internal IPS for Django. Use comma separated list +INTERNAL_IPS=127.0.0.1 + +# Enter the database url connection: https://github.com/jacobian/dj-database-url +DATABASE_URL=sqlite:////opt/development/synthea_webservice/webservice/db.sqlite3 + +# The location on disk where the static files will be placed during deployment. Setting is required +STATIC_ROOT= + +# Enter the default timezone for the visitors when it is not known. +TIME_ZONE=Europe/Amsterdam + +# Email settings + +# Mail host +EMAIL_HOST=192.168.5.1 + +# Email user name +EMAIL_HOST_USER=na + +# Email password +EMAIL_HOST_PASSWORD=na + +# Email server port number to use +EMAIL_PORT=25 + +# Does the email server supports TLS? +EMAIL_USE_TLS=yes + +# The sender address. This needs to be one of the allowed domains due to SPF checks +# The code will use a reply-to header to make sure that replies goes to the researcher and not this address +EMAIL_FROM_ADDRESS=Do not reply \ No newline at end of file diff --git a/webservice/webservice/.env.example b/webservice/webservice/.env.example new file mode 100644 index 0000000..5c59f24 --- /dev/null +++ b/webservice/webservice/.env.example @@ -0,0 +1,53 @@ +# A uniquely secret key +SECRET_KEY=@wb=#(f4uc0l%e!5*eo+aoflnxb(@!l9!=c5w=4b+x$=!8&vy%' + +# Disable debug in production +DEBUG=False + +# Allowed hosts that Django does server. Take care when NGINX is proxying infront of Django +ALLOWED_HOSTS=127.0.0.1,localhost + +# All internal IPS for Django. Use comma separated list +INTERNAL_IPS=127.0.0.1 + +# Enter the database url connection: https://github.com/jacobian/dj-database-url +DATABASE_URL=sqlite:////opt/deploy/VRE/VirtualResearchEnvironment/db.sqlite3 + +# The location on disk where the static files will be placed during deployment. Setting is required +STATIC_ROOT= + +# Enter the default timezone for the visitors when it is not known. +TIME_ZONE=Europe/Amsterdam + +# Email settings + +# Mail host +EMAIL_HOST= + +# Email user name +EMAIL_HOST_USER= + +# Email password +EMAIL_HOST_PASSWORD= + +# Email server port number to use +EMAIL_PORT=25 + +# Does the email server supports TLS? +EMAIL_USE_TLS= + +# The sender address. This needs to be one of the allowed domains due to SPF checks +# The code will use a reply-to header to make sure that replies goes to the researcher and not this address +EMAIL_FROM_ADDRESS=Do not reply + +# What is the Dropoff hostname (webinterface) +DROPOFF_HOSTNAME=http://localhost:8000 + +# What is the Dropoff Upload host +DROPOFF_UPLOAD_HOST=http://localhost + +# Which file extensions are **NOT** allowed +DROPOFF_NOT_ALLOWED_EXTENSIONS=exe,com,bat,lnk,sh + +# What is the full VRE Portal domains +VRE_BROKER_API=http://localhost:8000 \ No newline at end of file diff --git a/webservice/webservice/__init__.py b/webservice/webservice/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/webservice/webservice/asgi.py b/webservice/webservice/asgi.py new file mode 100644 index 0000000..eb81156 --- /dev/null +++ b/webservice/webservice/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for webservice project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webservice.settings') + +application = get_asgi_application() diff --git a/webservice/webservice/settings.py b/webservice/webservice/settings.py new file mode 100644 index 0000000..2aee057 --- /dev/null +++ b/webservice/webservice/settings.py @@ -0,0 +1,166 @@ +""" +Django settings for webservice project. + +Generated by 'django-admin startproject' using Django 3.1.3. + +For more information on this file, see +https://docs.djangoproject.com/en/3.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.1/ref/settings/ +""" + +from pathlib import Path +from decouple import config, Csv +from django.utils.translation import ugettext_lazy as _ +from dj_database_url import parse as db_url + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = config('SECRET_KEY') + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = config('DEBUG', default=False, cast=bool) + +ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='127.0.0.1', cast=Csv()) + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'django_js_reverse', + + 'apps.api', + 'apps.RUG_template', + 'apps.synthea', + + 'django.contrib.admin', # Admin add here, so that we can overrule the password reset template +] + +if DEBUG: + INSTALLED_APPS.append('debug_toolbar') + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +if DEBUG: + MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware') + +INTERNAL_IPS = config('INTERNAL_IPS',default='127.0.0.1',cast=Csv()) + +ROOT_URLCONF = 'webservice.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'webservice.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.1/ref/settings/#databases + +DATABASES = { + 'default': config( + 'DATABASE_URL', + default='sqlite:///' + str(BASE_DIR / 'db.sqlite3'), + cast=db_url + ) +} + + +# Password validation +# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + +# SSL Checks / Setup +# This will tell Django if the request is trough SSL (proxy). This is needed for Hawk authentication +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') + +# Internationalization +# https://docs.djangoproject.com/en/3.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +LANGUAGES = [ + ('nl', _('Dutch')), + ('en', _('English')), +] + +TIME_ZONE = config('TIME_ZONE', default='UTC') + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.1/howto/static-files/ + +STATIC_URL = '/static/' + +STATICFILES_DIRS = [ + BASE_DIR / 'static', +] + +STATIC_ROOT = config('STATIC_ROOT',None) + +EMAIL_FROM_ADDRESS = config('EMAIL_FROM_ADDRESS', default='Do not reply') +EMAIL_HOST = config('EMAIL_HOST', default='') +EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='') +EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='') +EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int) +EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool) + +DEFAULT_FROM_EMAIL = EMAIL_FROM_ADDRESS + +if DEBUG: + EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' + EMAIL_FILE_PATH = BASE_DIR / 'sent_emails' \ No newline at end of file diff --git a/webservice/webservice/urls.py b/webservice/webservice/urls.py new file mode 100644 index 0000000..ba9474e --- /dev/null +++ b/webservice/webservice/urls.py @@ -0,0 +1,36 @@ +"""webservice URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.conf import settings +from django.contrib import admin +from django.urls import path, include +from django_js_reverse.views import urls_js + +urlpatterns = [ + path('admin/', admin.site.urls), + + path('', include('apps.synthea.urls')), + + # Add Default RUG HTML homepage + path('', include('apps.RUG_template.urls')), + path('jsreverse/', urls_js, name='js_reverse'), + path('i18n/', include('django.conf.urls.i18n')), +] + +if settings.DEBUG: + import debug_toolbar + urlpatterns = [ + path('__debug__/', include(debug_toolbar.urls)), + ] + urlpatterns \ No newline at end of file diff --git a/webservice/webservice/wsgi.py b/webservice/webservice/wsgi.py new file mode 100644 index 0000000..5451acf --- /dev/null +++ b/webservice/webservice/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for webservice project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'webservice.settings') + +application = get_wsgi_application()