Update and fixes

This commit is contained in:
JensDiemer 2021-10-10 14:35:06 +02:00
parent 07c9eef7d5
commit dca8f22b69
20 changed files with 1246 additions and 1007 deletions

View file

@ -1,11 +1,12 @@
name: YunoHost apps package linter name: YunoHost apps package linter
on: on:
schedule:
- cron: '0 8 * * *'
push: push:
branches: branches:
- main - main
pull_request:
schedule:
- cron: '0 8 * * *'
jobs: jobs:
test: test:

View file

@ -1,11 +1,12 @@
name: pytest name: pytest
on: on:
schedule:
- cron: '0 8 * * *'
push: push:
branches: branches:
- main - main
pull_request:
schedule:
- cron: '0 8 * * *'
jobs: jobs:
test: test:

104
README.md
View file

@ -1,33 +1,78 @@
# Django-ForRunners for YunoHost # django-for-runners for YunoHost
[![Integration level](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg) [![Integration level](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) [![CI Pipeline](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg)](https://ci-apps-dev.yunohost.org/ci/) [![Maintain status](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg)](https://dash.yunohost.org/appci/app/django-for-runners)
[![Install Django-ForRunners with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=django-for-runners)
> *This package allows you to install Django-ForRunners quickly and simply on a YunoHost server. [![Build Status on github](https://github.com/YunoHost-Apps/django-for-runners_ynh/workflows/pytest/badge.svg)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions) [![.github/workflows/package_linter.yml](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/django-for-runners_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/django-for-runners_ynh)
[![Install django-for-runners with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
> *This package allows you to install django-for-runners quickly and simply on a YunoHost server.
If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.*
Current status is pre-alpha: This app doesn't work, yet ;)
Pull requests welcome ;) Pull requests welcome ;)
## Overview ## Overview
Django-ForRunners is a libre web-based management to catalog things including state and location etc. using Python/Django. ![Logo](https://raw.githubusercontent.com/jedie/django-for-runners/master/src/django-for-runners/static/django-for-runners128.png)
[django-for-runners](https://github.com/jedie/django-for-runners) is a libre web-based management for your GPX tracks of your running (or other sports activity). Used [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
## Screenshots ## Screenshots
![](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runers%20v0.6.0%202018-07-31%20GPX%20Track.png)
![](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runners%20v0.4.0%202018-6-26%20GPX%20info.png)
![](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runners%20v0.6.0%202018-07-19%20Event%20Costs.png)
## Admin account
An admin user is created at installation, the login is what you provided at installation, the password is **django-for-runners**. More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
----
![v0.6.0 2018-07-31 GPX Track](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runers%20v0.6.0%202018-07-31%20GPX%20Track.png)
----
![v0.4.0 2018-6-26 GPX info.png](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runners%20v0.4.0%202018-6-26%20GPX%20info.png)
----
![v0.6.0 2018-07-19 Event Costs](https://raw.githubusercontent.com/jedie/jedie.github.io/master/screenshots/django-for-runners/for-runners%20v0.6.0%202018-07-19%20Event%20Costs.png)
----
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
## Settings and upgrades ## Settings and upgrades
Almost everything related to Django-ForRunners's configuration is handled in a `"../conf/ynh_for_runners_settings.py"` file. Almost everything related to django-for-runners's configuration is handled in a `"../conf/settings.py"` file.
You can edit the file `$final_path/local_settings.py` to enable or disable features. You can edit the file `/opt/yunohost/django-for-runners/local_settings.py` to enable or disable features.
Test sending emails:
```bash
ssh admin@yourdomain.tld
root@yunohost:~# cd /opt/yunohost/django-for-runners/
root@yunohost:/opt/yunohost/django-for-runners# source venv/bin/activate
(venv) root@yunohost:/opt/yunohost/django-for-runners# ./manage.py sendtestemail --admins
```
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
To check current ADMINS run:
```bash
(venv) root@yunohost:/opt/yunohost/django-for-runners# ./manage.py sendtestemail --admins
```
If you prefere to send error emails to a extrnal email address, just do something like this:
```bash
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/django-for-runners/local_settings.py
```
To check the effective settings, run this:
```bash
(venv) root@yunohost:/opt/yunohost/django-for-runners# ./manage.py diffsettings
```
# Miscellaneous # Miscellaneous
@ -45,7 +90,7 @@ You can edit the file `$final_path/local_settings.py` to enable or disable featu
## Links ## Links
* Report a bug about this package: https://github.com/YunoHost-Apps/django-for-runners_ynh * Report a bug about this package: https://github.com/YunoHost-Apps/django-for-runners_ynh
* Report a bug about Django-ForRunners itself: https://github.com/jedie/django-for-runners * Report a bug about django-for-runners itself: https://github.com/jedie/django-for-runners
* YunoHost website: https://yunohost.org/ * YunoHost website: https://yunohost.org/
--- ---
@ -75,6 +120,17 @@ To remove call e.g.:
sudo yunohost app remove django-for-runners sudo yunohost app remove django-for-runners
``` ```
Backup / remove / restore cycle, e.g.:
```bash
yunohost backup create --apps django-for-runners
yunohost backup list
archives:
- django-for-runners-pre-upgrade1
- 20201223-163434
yunohost app remove django-for-runners
yunohost backup restore 20201223-163434 --apps django-for-runners
```
Debug installation, e.g.: Debug installation, e.g.:
```bash ```bash
root@yunohost:~# ls -la /var/www/django-for-runners/ root@yunohost:~# ls -la /var/www/django-for-runners/
@ -94,27 +150,27 @@ drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
-rw-r--r-- 1 django-for-runners django-for-runners 171 Dec 8 08:39 secret.txt -rw-r--r-- 1 django-for-runners django-for-runners 171 Dec 8 08:39 secret.txt
drwxr-xr-x 6 django-for-runners django-for-runners 6 Dec 8 08:37 venv drwxr-xr-x 6 django-for-runners django-for-runners 6 Dec 8 08:37 venv
-rw-r--r-- 1 django-for-runners django-for-runners 115 Dec 8 08:39 wsgi.py -rw-r--r-- 1 django-for-runners django-for-runners 115 Dec 8 08:39 wsgi.py
-rw-r--r-- 1 django-for-runners django-for-runners 4737 Dec 8 08:39 ynh_for_runners_settings.py -rw-r--r-- 1 django-for-runners django-for-runners 4737 Dec 8 08:39 settings.py
root@yunohost:~# cd /opt/yunohost/django-for-runners/ root@yunohost:~# cd /opt/yunohost/django-for-runners/
root@yunohost:/opt/yunohost/django-for-runners# source venv/bin/activate root@yunohost:/opt/yunohost/django-for-runners# source venv/bin/activate
(venv) root@yunohost:/opt/yunohost/django-for-runners# ./manage.py check (venv) root@yunohost:/opt/yunohost/django-for-runners# ./manage.py check
Django-ForRunners v0.12.0 (Django v2.2.17) django-for-runners v0.8.2 (Django v2.2.17)
DJANGO_SETTINGS_MODULE='ynh_django-for-runners_settings' DJANGO_SETTINGS_MODULE='settings'
PROJECT_PATH:/opt/yunohost/django-for-runners/venv/lib/python3.7/site-packages PROJECT_PATH:/opt/yunohost/django-for-runners/venv/lib/python3.7/site-packages
BASE_PATH:/opt/yunohost/django-for-runners BASE_PATH:/opt/yunohost/django-for-runners
System check identified no issues (0 silenced). System check identified no issues (0 silenced).
root@yunohost:~# tail -f /var/log/django-for-runners/django-for-runners.log root@yunohost:~# tail -f /var/log/django-for-runners/django-for-runners.log
root@yunohost:~# cat /etc/systemd/system/for_runners.service root@yunohost:~# cat /etc/systemd/system/django-for-runners.service
root@yunohost:~# systemctl reload-or-restart django-for-runners root@yunohost:~# systemctl reload-or-restart django-for-runners
root@yunohost:~# journalctl --unit=django-for-runners --follow root@yunohost:~# journalctl --unit=for_runners --follow
``` ```
## local test ## local test
For quicker developing of Django-ForRunners in the context of YunoHost app, For quicker developing of django-for-runners in the context of YunoHost app,
it's possible to run the Django developer server with the settings it's possible to run the Django developer server with the settings
and urls made for YunoHost installation. and urls made for YunoHost installation.
@ -124,11 +180,9 @@ e.g.:
~$ cd django-for-runners_ynh/ ~$ cd django-for-runners_ynh/
~/django-for-runners_ynh$ make ~/django-for-runners_ynh$ make
install-poetry install or update poetry install-poetry install or update poetry
install install project via poetry install install django-for-runners via poetry
update update the sources and installation update update the sources and installation
local-test Run local_test.py to run the project locally local-test Run local_test.py to run django-for-runners_ynh locally
local-diff-settings Run "manage.py diffsettings" with local test
~/django-for-runners_ynh$ make install-poetry ~/django-for-runners_ynh$ make install-poetry
~/django-for-runners_ynh$ make install ~/django-for-runners_ynh$ make install
~/django-for-runners_ynh$ make local-test ~/django-for-runners_ynh$ make local-test

View file

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Django-ForRunners application server Description=django-for-runners application server
After=redis.service postgresql.service After=redis.service postgresql.service
[Service] [Service]

View file

@ -1,348 +1,372 @@
autotask==0.5.4; python_version >= "3.7" and python_full_version < "4.0.0" \ autotask==0.5.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:d21578ab14adafb0d9be3490a444d261fd2bcdcbb1ee941b28d4b5e5d1a386ad --hash=sha256:d21578ab14adafb0d9be3490a444d261fd2bcdcbb1ee941b28d4b5e5d1a386ad
bleach==3.2.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ bleach==4.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:9f8ccbeb6183c6e6cddea37592dfb0167485c1e3b13b3363bc325aa8bda3adbd \ --hash=sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994 \
--hash=sha256:52b5919b81842b1854196eaae5ca29679a2f2e378905c346d3ca8227c2c66080 --hash=sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da
bx-py-utils==20; python_version >= "3.6" and python_full_version < "4.0.0" \ bx-py-utils==46; python_version >= "3.6" and python_full_version < "4.0.0" \
--hash=sha256:8b7d21e89e5cc99e400ab0bd910632c2d79c7b27aa45afaaa65f4dec2274496e \ --hash=sha256:ea7137ec2fa51e1e982d2e55b9cdf1d5ce487e01cba1d8c76be392947011cc3d \
--hash=sha256:4fc9b3a78bf82a02ee5d823f45af4623f8c3bec360434b4ae4b87d01cc0ff03a --hash=sha256:846a0c2b95f96c361d9f9d6cf87f2893bd5d81a61bade446a8010f0e5d95c0f3
certifi==2020.12.5; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ certifi==2021.10.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830 \ --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569 \
--hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872
chardet==4.0.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ charset-normalizer==2.0.6; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5 \ --hash=sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f \
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa --hash=sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6
click==7.1.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ click==8.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc \ --hash=sha256:3fab8aeb8f15f5452ae7511ad448977b3417325bceddd53df87e0bb81f3a8cf8 \
--hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a --hash=sha256:7027bc7bbafaab8b2c2816861d8eb372429ee3c02e193fc2f93d6c4ab9de49c5
colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and sys_platform == "win32" and python_full_version >= "3.5.0" \ colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and platform_system == "Windows" and python_full_version >= "3.5.0" and sys_platform == "win32" \
--hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \
--hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b
colorlog==4.7.2; python_version >= "3.7" and python_full_version < "4.0.0" \ colorlog==6.5.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:0a9dcdba6cab68e8a768448b418a858d73c52b37b6e8dea2568296faece393bd \ --hash=sha256:d334b1b8dae5989b786232f05586a7a0111feb24ff9cfc8310c3347a91388717 \
--hash=sha256:18d05b616438a75762d7d214b9ec3b05d274466c9f3ddd92807e755840c88251 --hash=sha256:cf62a8e389d5660d0d22be17937b25b9abef9497ddc940197d1773aa1f604339
cycler==0.10.0; python_version >= "3.7" and python_full_version < "4.0.0" \ cycler==0.10.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d \ --hash=sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d \
--hash=sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8 --hash=sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8
defusedxml==0.6.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ defusedxml==0.7.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \
--hash=sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93 \ --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 \
--hash=sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5 --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69
diff-match-patch==20200713; python_version >= "3.7" and python_full_version < "4.0.0" \ diff-match-patch==20200713; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18 \ --hash=sha256:da6f5a01aa586df23dfc89f3827e1cafbb5420be9d87769eeb079ddfd9477a18 \
--hash=sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34 --hash=sha256:8bf9d9c4e059d917b5c6312bac0c137971a32815ddbda9c682b949f2986b4d34
django-axes==5.12.0; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ django-axes==5.25.0; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \
--hash=sha256:c26167f7ca2003df8358eb23537dffb1d97bd9f44ccef70d5c64a7aba2349456 \ --hash=sha256:835327df91e039c3eb7479441b7b3cbcc5aecc25025753c5ae00969309b23dd6 \
--hash=sha256:db4e17fad2e07baa02bb210c5f819fb5137c548e3a5a4330ccc8662bb88d42c7 --hash=sha256:c72e19981aae1426dc356b9e69a6e168b3e7e91ff305beec9a375a232f579724
django-dbbackup==3.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \ django-dbbackup==3.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8 --hash=sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8
django-debug-toolbar==3.2; python_version >= "3.7" and python_full_version < "4.0.0" \ django-debug-toolbar==3.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:84e2607d900dbd571df0a2acf380b47c088efb787dce9805aefeb407341961d2 \ --hash=sha256:8c5b13795d4040008ee69ba82dcdd259c49db346cf7d0de6e561a49d191f0860 \
--hash=sha256:9e5a25d0c965f7e686f6a8ba23613ca9ca30184daa26487706d4829f5cfb697a --hash=sha256:d7bab7573fab35b0fd029163371b7182f5826c13da69734beb675c761d06a4d3
django-for-runners==0.12.0; python_version >= "3.7" and python_full_version < "4.0.0" \ django-for-runners==0.12.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:373cc67f6357910ad9b45fb78d0d13a3fa5b78738c047c2be795716d31fecba6 \ --hash=sha256:373cc67f6357910ad9b45fb78d0d13a3fa5b78738c047c2be795716d31fecba6 \
--hash=sha256:7abb9cf734fe9e35beb1c96457405d2672a7bf5dcc682c759caa8dd24a92367d --hash=sha256:7abb9cf734fe9e35beb1c96457405d2672a7bf5dcc682c759caa8dd24a92367d
django-import-export==2.5.0; python_version >= "3.7" and python_full_version < "4.0.0" \ django-import-export==2.6.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:c39c003bfc803fb63ba7742562f1667603a4a8d7426261845d75ce8582d40f48 \ --hash=sha256:056624f3d6af04f74ed7adc0ba64841a9ff033162432c668877b53a6832e6c57 \
--hash=sha256:cf6f3dabdd4f32dcb26e25c7ddcba7aee3168b55d380b0da79f0349afa17c011 --hash=sha256:c8509fcc5176a34f1c90fc15aeaedcb8011c6a397ef64caf0b38eabcd723a9f9
django-ipware==3.0.2; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ django-ipware==4.0.0; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4.0" or python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:c7df8e1410a8e5d6b1fbae58728402ea59950f043c3582e033e866f0f0cf5e94 --hash=sha256:1294f916f3b3475e40e1b0ec1bd320aa2397978eae672721c81cbc2ed517e9ee \
--hash=sha256:116bd0d7940f09bf7ffd465943992e23d87e772a9d6c0d3a57b74040589a383b
django-processinfo==1.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \ django-processinfo==1.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:3cacad233a5428a5cc6292eafbfddd97948d8d1e4f47e47175a7fcdfcee90f12 \ --hash=sha256:3cacad233a5428a5cc6292eafbfddd97948d8d1e4f47e47175a7fcdfcee90f12 \
--hash=sha256:08aefdf7285d1eaa595e46570bcc12f2dfd9e24594d524246110614819076b6c --hash=sha256:08aefdf7285d1eaa595e46570bcc12f2dfd9e24594d524246110614819076b6c
django-redis==4.12.1; python_version >= "3.5" \ django-redis==5.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:306589c7021e6468b2656edc89f62b8ba67e8d5a1c8877e2688042263daa7a63 \ --hash=sha256:048f665bbe27f8ff2edebae6aa9c534ab137f1e8fa7234147ef470df3f3aa9b8 \
--hash=sha256:1133b26b75baa3664164c3f44b9d5d133d1b8de45d94d79f38d1adc5b1d502e5 --hash=sha256:97739ca9de3f964c51412d1d7d8aecdfd86737bb197fce6e1ff12620c63c97ee
django-tools==0.48.3; python_version >= "3.7" and python_full_version < "4.0.0" \ django-tools==0.48.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:08ed2ae606067f49c2c3949055227a826c8b880e5816114925eca386cf1823af \ --hash=sha256:08ed2ae606067f49c2c3949055227a826c8b880e5816114925eca386cf1823af \
--hash=sha256:40444fa16b703b7c6960a800ba76aad42472c9aa70040d549a4d91dbb47a5ddb --hash=sha256:40444fa16b703b7c6960a800ba76aad42472c9aa70040d549a4d91dbb47a5ddb
django-ynh==0.1.4; python_version >= "3.7" and python_full_version < "4.0.0" \ django-yunohost-integration==0.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:29250e9dd615f83772a7dc50f25706ebe4e8b776f576d1ed43f6c60289ecd26b \ --hash=sha256:e5290ea079bf0f340c73445b9655957fafa1dd4042ae8dcf3ace2f903fceda05 \
--hash=sha256:35788a7b91a685a80b15f462796fedb604752c2c8957a6edfb0a777346efa66e --hash=sha256:5f6c02a9bffb90449a2bcefc8f75736da8731c4aea6c033b5c35ff8906b79424
django==2.2.17; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \ django==2.2.24; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \
--hash=sha256:558cb27930defd9a6042133258caf797b2d1dee233959f537e3dc475cb49bd7c \ --hash=sha256:f2084ceecff86b1e631c2cd4107d435daf4e12f1efcdf11061a73bf0b5e95f92 \
--hash=sha256:cf5370a4d7765a9dd6d42a7b96b53c74f9446cd38209211304b210fe0404b861 --hash=sha256:3339ff0e03dee13045aef6ae7b523edff75b6d726adf7a7a48f53d5a501f7db7
et-xmlfile==1.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \ et-xmlfile==1.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b --hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada \
geographiclib==1.50; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c
--hash=sha256:51cfa698e7183792bce27d8fb63ac8e83689cd8170a730bf35e1a5c5bf8849b9 \ geographiclib==1.52; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:12bd46ee7ec25b291ea139b17aa991e7ef373e21abd053949b75c0e9ca55c632 --hash=sha256:8f441c527b0b8a26cd96c965565ff0513d1e4d9952b704bf449409e5015c77b7 \
geopy==2.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:ac400d672b8954b0306bca890b088bb8ba2a757dc8133cca0b878f34b33b2740
--hash=sha256:4db8a2b79a2b3358a7d020ea195be639251a831a1b429c0d1b20c9f00c67c788 \ geopy==2.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:892b219413e7955587b029949af3a1949c6fbac9d5ad17b79d850718f6a9550f --hash=sha256:8f1f949082b964385de61fcc3a667a6a9a6e242beb1ae8972449f164b2ba0e89 \
--hash=sha256:58b7edf526b8c32e33126570b5f4fcdfaa29d4416506064777ae8d84cd103fdd
gpxpy==1.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \ gpxpy==1.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:0832041899cdfdc5a607291bbef3d73042e16ffcecc3f2cb9631b699db0bb53f --hash=sha256:0832041899cdfdc5a607291bbef3d73042e16ffcecc3f2cb9631b699db0bb53f
gunicorn==20.0.4; python_version >= "3.4" \ gunicorn==20.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c \ --hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8
--hash=sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626 icdiff==2.0.4; python_version >= "3.7" and python_full_version < "4.0.0" \
icdiff==1.9.1; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:c72572e5ce087bc7a7748af2664764d4a805897caeefb665bdc12677fefb2212
--hash=sha256:66972dd03318da55280991db375d3ef6b66d948c67af96c1ebdb21587e86655e idna==3.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
idna==2.10; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a \
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \ --hash=sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 importlib-metadata==4.8.1; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
jdcal==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15 \
--hash=sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba \ --hash=sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1
--hash=sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8 kiwisolver==1.3.2; python_version >= "3.7" and python_full_version < "4.0.0" \
kiwisolver==1.3.1; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6 \
--hash=sha256:fd34fbbfbc40628200730bc1febe30631347103fc8d3d4fa012c21ab9c11eca9 \ --hash=sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470 \
--hash=sha256:d3155d828dec1d43283bd24d3d3e0d9c7c350cdfcc0bd06c0ad1209c1bbc36d0 \ --hash=sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298 \
--hash=sha256:5a7a7dbff17e66fac9142ae2ecafb719393aaee6a3768c9de2fd425c63b53e21 \ --hash=sha256:2210f28778c7d2ee13f3c2a20a3a22db889e75f4ec13a21072eabb5693801e84 \
--hash=sha256:f8d6f8db88049a699817fd9178782867bf22283e3813064302ac59f61d95be05 \ --hash=sha256:82f49c5a79d3839bc8f38cb5f4bfc87e15f04cbafa5fbd12fb32c941cb529cfb \
--hash=sha256:5f6ccd3dd0b9739edcf407514016108e2280769c73a85b9e59aa390046dbf08b \ --hash=sha256:9661a04ca3c950a8ac8c47f53cbc0b530bce1b52f516a1e87b7736fec24bfff0 \
--hash=sha256:225e2e18f271e0ed8157d7f4518ffbf99b9450fca398d561eb5c4a87d0986dd9 \ --hash=sha256:2ddb500a2808c100e72c075cbb00bf32e62763c82b6a882d403f01a119e3f402 \
--hash=sha256:cf8b574c7b9aa060c62116d4181f3a1a4e821b2ec5cbfe3775809474113748d4 \ --hash=sha256:72be6ebb4e92520b9726d7146bc9c9b277513a57a38efcf66db0620aec0097e0 \
--hash=sha256:232c9e11fd7ac3a470d65cd67e4359eee155ec57e822e5220322d7b2ac84fbf0 \ --hash=sha256:83d2c9db5dfc537d0171e32de160461230eb14663299b7e6d18ca6dca21e4977 \
--hash=sha256:b38694dcdac990a743aa654037ff1188c7a9801ac3ccc548d3341014bc5ca278 \ --hash=sha256:cba430db673c29376135e695c6e2501c44c256a81495da849e85d1793ee975ad \
--hash=sha256:ca3820eb7f7faf7f0aa88de0e54681bddcb46e485beb844fcecbcd1c8bd01689 \ --hash=sha256:4116ba9a58109ed5e4cb315bdcbff9838f3159d099ba5259c7c7fb77f8537492 \
--hash=sha256:c8fd0f1ae9d92b42854b2979024d7597685ce4ada367172ed7c09edf2cef9cb8 \ --hash=sha256:19554bd8d54cf41139f376753af1a644b63c9ca93f8f72009d50a2080f870f77 \
--hash=sha256:1e1bc12fb773a7b2ffdeb8380609f4f8064777877b2225dec3da711b421fda31 \ --hash=sha256:a7a4cf5bbdc861987a7745aed7a536c6405256853c94abc9f3287c3fa401b174 \
--hash=sha256:72c99e39d005b793fb7d3d4e660aed6b6281b502e8c1eaf8ee8346023c8e03bc \ --hash=sha256:0007840186bacfaa0aba4466d5890334ea5938e0bb7e28078a0eb0e63b5b59d5 \
--hash=sha256:8be8d84b7d4f2ba4ffff3665bcd0211318aa632395a1a41553250484a871d454 \ --hash=sha256:ec2eba188c1906b05b9b49ae55aae4efd8150c61ba450e6721f64620c50b59eb \
--hash=sha256:31dfd2ac56edc0ff9ac295193eeaea1c0c923c0355bf948fbd99ed6018010b72 \ --hash=sha256:3dbb3cea20b4af4f49f84cffaf45dd5f88e8594d18568e0225e6ad9dec0e7967 \
--hash=sha256:563c649cfdef27d081c84e72a03b48ea9408c16657500c312575ae9d9f7bc1c3 \ --hash=sha256:5326ddfacbe51abf9469fe668944bc2e399181a2158cb5d45e1d40856b2a0589 \
--hash=sha256:78751b33595f7f9511952e7e60ce858c6d64db2e062afb325985ddbd34b5c131 \ --hash=sha256:c6572c2dab23c86a14e82c245473d45b4c515314f1f859e92608dcafbd2f19b8 \
--hash=sha256:a357fd4f15ee49b4a98b44ec23a34a95f1e00292a139d6015c11f55774ef10de \ --hash=sha256:b5074fb09429f2b7bc82b6fb4be8645dcbac14e592128beeff5461dcde0af09f \
--hash=sha256:5989db3b3b34b76c09253deeaf7fbc2707616f130e166996606c284395da3f18 \ --hash=sha256:22521219ca739654a296eea6d4367703558fba16f98688bd8ce65abff36eaa84 \
--hash=sha256:c08e95114951dc2090c4a630c2385bef681cacf12636fb0241accdc6b303fd81 \ --hash=sha256:c358721aebd40c243894298f685a19eb0491a5c3e0b923b9f887ef1193ddf829 \
--hash=sha256:44a62e24d9b01ba94ae7a4a6c3fb215dc4af1dde817e7498d901e229aaf50e4e \ --hash=sha256:7ba5a1041480c6e0a8b11a9544d53562abc2d19220bfa14133e0cdd9967e97af \
--hash=sha256:50af681a36b2a1dee1d3c169ade9fdc59207d3c31e522519181e12f1b3ba7000 \ --hash=sha256:44e6adf67577dbdfa2d9f06db9fbc5639afefdb5bf2b4dfec25c3a7fbc619536 \
--hash=sha256:a53d27d0c2a0ebd07e395e56a1fbdf75ffedc4a05943daf472af163413ce9598 \ --hash=sha256:1d45d1c74f88b9f41062716c727f78f2a59a5476ecbe74956fafb423c5c87a76 \
--hash=sha256:834ee27348c4aefc20b479335fd422a2c69db55f7d9ab61721ac8cd83eb78882 \ --hash=sha256:70adc3658138bc77a36ce769f5f183169bc0a2906a4f61f09673f7181255ac9b \
--hash=sha256:5c3e6455341008a054cccee8c5d24481bcfe1acdbc9add30aa95798e95c65621 \ --hash=sha256:b6a5431940f28b6de123de42f0eb47b84a073ee3c3345dc109ad550a3307dd28 \
--hash=sha256:acef3d59d47dd85ecf909c359d0fd2c81ed33bdff70216d3956b463e12c38a54 \ --hash=sha256:ee040a7de8d295dbd261ef2d6d3192f13e2b08ec4a954de34a6fb8ff6422e24c \
--hash=sha256:c5518d51a0735b1e6cee1fdce66359f8d2b59c3ca85dc2b0813a8aa86818a030 \ --hash=sha256:8dc3d842fa41a33fe83d9f5c66c0cc1f28756530cd89944b63b072281e852031 \
--hash=sha256:b9edd0110a77fc321ab090aaa1cfcaba1d8499850a12848b81be2222eab648f6 \ --hash=sha256:a498bcd005e8a3fedd0022bb30ee0ad92728154a8798b703f394484452550507 \
--hash=sha256:0cd53f403202159b44528498de18f9285b04482bab2a6fc3f5dd8dbb9352e30d \ --hash=sha256:80efd202108c3a4150e042b269f7c78643420cc232a0a771743bb96b742f838f \
--hash=sha256:33449715e0101e4d34f64990352bce4095c8bf13bed1b390773fc0a7295967b3 \ --hash=sha256:f8eb7b6716f5b50e9c06207a14172cf2de201e41912ebe732846c02c830455b9 \
--hash=sha256:401a2e9afa8588589775fe34fc22d918ae839aaaf0c0e96441c0fdbce6d8ebe6 \ --hash=sha256:f441422bb313ab25de7b3dbfd388e790eceb76ce01a18199ec4944b369017009 \
--hash=sha256:950a199911a8d94683a6b10321f9345d5a3a8433ec58b217ace979e18f16e248 --hash=sha256:30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6 \
lxml==4.6.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:2f8f6c8f4f1cff93ca5058d6ec5f0efda922ecb3f4c5fb76181f327decff98b8 \
--hash=sha256:a9d6bc8642e2c67db33f1247a77c53476f3a166e09067c0474facb045756087f \ --hash=sha256:ba677bcaff9429fd1bf01648ad0901cea56c0d068df383d5f5856d88221fe75b \
--hash=sha256:791394449e98243839fa822a637177dd42a95f4883ad3dec2a0ce6ac99fb0a9d \ --hash=sha256:7843b1624d6ccca403a610d1277f7c28ad184c5aa88a1750c1a999754e65b439 \
--hash=sha256:68a5d77e440df94011214b7db907ec8f19e439507a70c958f750c18d88f995d2 \ --hash=sha256:e6f5eb2f53fac7d408a45fbcdeda7224b1cfff64919d0f95473420a931347ae9 \
--hash=sha256:fc37870d6716b137e80d19241d0e2cff7a7643b925dfa49b4c8ebd1295eb506e \ --hash=sha256:eedd3b59190885d1ebdf6c5e0ca56828beb1949b4dfe6e5d0256a461429ac386 \
--hash=sha256:69a63f83e88138ab7642d8f61418cf3180a4d8cd13995df87725cb8b893e950e \ --hash=sha256:dedc71c8eb9c5096037766390172c34fb86ef048b8e8958b4e484b9e505d66bc \
--hash=sha256:42ebca24ba2a21065fb546f3e6bd0c58c3fe9ac298f3a320147029a4850f51a2 \ --hash=sha256:bf7eb45d14fc036514c09554bf983f2a72323254912ed0c3c8e697b62c4c158f \
--hash=sha256:f83d281bb2a6217cd806f4cf0ddded436790e66f393e124dfe9731f6b3fb9afe \ --hash=sha256:2b65bd35f3e06a47b5c30ea99e0c2b88f72c6476eedaf8cfbc8e66adb5479dcf \
--hash=sha256:535f067002b0fd1a4e5296a8f1bf88193080ff992a195e66964ef2a6cfec5388 \ --hash=sha256:25405f88a37c5f5bcba01c6e350086d65e7465fd1caaf986333d2a045045a223 \
--hash=sha256:366cb750140f221523fa062d641393092813b81e15d0e25d9f7c6025f910ee80 \ --hash=sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560 \
--hash=sha256:97db258793d193c7b62d4e2586c6ed98d51086e93f9a3af2b2034af01450a74b \ --hash=sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c
--hash=sha256:648914abafe67f11be7d93c1a546068f8eff3c5fa938e1f94509e4a5d682b2d8 \ lxml==4.6.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \
--hash=sha256:4e751e77006da34643ab782e4a5cc21ea7b755551db202bc4d3a423b307db780 \ --hash=sha256:df7c53783a46febb0e70f6b05df2ba104610f2fb0d27023409734a3ecbb78fb2 \
--hash=sha256:681d75e1a38a69f1e64ab82fe4b1ed3fd758717bed735fb9aeaa124143f051af \ --hash=sha256:1b7584d421d254ab86d4f0b13ec662a9014397678a7c4265a02a6d7c2b18a75f \
--hash=sha256:127f76864468d6630e1b453d3ffbbd04b024c674f55cf0a30dc2595137892d37 \ --hash=sha256:079f3ae844f38982d156efce585bc540c16a926d4436712cf4baee0cce487a3d \
--hash=sha256:4fb85c447e288df535b17ebdebf0ec1cf3a3f1a8eba7e79169f4f37af43c6b98 \ --hash=sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106 \
--hash=sha256:5be4a2e212bb6aa045e37f7d48e3e1e4b6fd259882ed5a00786f82e8c37ce77d \ --hash=sha256:8157dadbb09a34a6bd95a50690595e1fa0af1a99445e2744110e3dca7831c4ee \
--hash=sha256:8c88b599e226994ad4db29d93bc149aa1aff3dc3a4355dd5757569ba78632bdf \ --hash=sha256:7728e05c35412ba36d3e9795ae8995e3c86958179c9770e65558ec3fdfd3724f \
--hash=sha256:6e4183800f16f3679076dfa8abf2db3083919d7e30764a069fb66b2b9eff9939 \ --hash=sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4 \
--hash=sha256:d8d3d4713f0c28bdc6c806a278d998546e8efc3498949e3ace6e117462ac0a5e \ --hash=sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51 \
--hash=sha256:8246f30ca34dc712ab07e51dc34fea883c00b7ccb0e614651e49da2c49a30711 \ --hash=sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586 \
--hash=sha256:923963e989ffbceaa210ac37afc9b906acebe945d2723e9679b643513837b089 \ --hash=sha256:4c61b3a0db43a1607d6264166b230438f85bfed02e8cff20c22e564d0faff354 \
--hash=sha256:1471cee35eba321827d7d53d104e7b8c593ea3ad376aa2df89533ce8e1b24a01 \ --hash=sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16 \
--hash=sha256:2363c35637d2d9d6f26f60a208819e7eafc4305ce39dc1d5005eccc4593331c2 \ --hash=sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2 \
--hash=sha256:f4822c0660c3754f1a41a655e37cb4dbbc9be3d35b125a37fab6f82d47674ebc \ --hash=sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4 \
--hash=sha256:0448576c148c129594d890265b1a83b9cd76fd1f0a6a04620753d9a6bcfd0a4d \ --hash=sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4 \
--hash=sha256:60a20bfc3bd234d54d49c388950195d23a5583d4108e1a1d47c9eef8d8c042b3 \ --hash=sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3 \
--hash=sha256:2e5cc908fe43fe1aa299e58046ad66981131a66aea3129aac7770c37f590a644 \ --hash=sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d \
--hash=sha256:50c348995b47b5a4e330362cf39fc503b4a43b14a91c34c83b955e1805c8e308 \ --hash=sha256:d916d31fd85b2f78c76400d625076d9124de3e4bda8b016d25a050cc7d603f24 \
--hash=sha256:94d55bd03d8671686e3f012577d9caa5421a07286dd351dfef64791cf7c6c505 \ --hash=sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec \
--hash=sha256:7a7669ff50f41225ca5d6ee0a1ec8413f3a0d8aa2b109f86d540887b7ec0d72a \ --hash=sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617 \
--hash=sha256:e0bfe9bb028974a481410432dbe1b182e8191d5d40382e5b8ff39cdd2e5c5931 \ --hash=sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04 \
--hash=sha256:6fd8d5903c2e53f49e99359b063df27fdf7acb89a52b6a12494208bf61345a03 \ --hash=sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a \
--hash=sha256:7e9eac1e526386df7c70ef253b792a0a12dd86d833b1d329e038c7a235dfceb5 \ --hash=sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654 \
--hash=sha256:7ee8af0b9f7de635c61cdd5b8534b76c52cd03536f29f51151b377f76e214a1a \ --hash=sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0 \
--hash=sha256:2e6fd1b8acd005bd71e6c94f30c055594bbd0aa02ef51a22bbfa961ab63b2d75 \ --hash=sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3 \
--hash=sha256:535332fe9d00c3cd455bd3dd7d4bacab86e2d564bdf7606079160fa6251caacf \ --hash=sha256:36108c73739985979bf302006527cf8a20515ce444ba916281d1c43938b8bb96 \
--hash=sha256:cd11c7e8d21af997ee8079037fff88f16fda188a9776eb4b81c7e4c9c0a7d7fc --hash=sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2 \
--hash=sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92 \
--hash=sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade \
--hash=sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b \
--hash=sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa \
--hash=sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a \
--hash=sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927 \
--hash=sha256:e1cbd3f19a61e27e011e02f9600837b921ac661f0c40560eefb366e4e4fb275e \
--hash=sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791 \
--hash=sha256:1b38116b6e628118dea5b2186ee6820ab138dbb1e24a13e478490c7db2f326ae \
--hash=sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28 \
--hash=sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7 \
--hash=sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0 \
--hash=sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1 \
--hash=sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23 \
--hash=sha256:3082c518be8e97324390614dacd041bb1358c882d77108ca1957ba47738d9d59 \
--hash=sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969 \
--hash=sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a \
--hash=sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f \
--hash=sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83 \
--hash=sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468
markuppy==1.14; python_version >= "3.7" and python_full_version < "4.0.0" \ markuppy==1.14; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f --hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f
matplotlib==3.3.3; python_version >= "3.7" and python_full_version < "4.0.0" \ matplotlib==3.4.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:b2a5e1f637a92bb6f3526cc54cc8af0401112e81ce5cba6368a1b7908f9e18bc \ --hash=sha256:5c988bb43414c7c2b0a31bd5187b4d27fd625c080371b463a6d422047df78913 \
--hash=sha256:c586ac1d64432f92857c3cf4478cfb0ece1ae18b740593f8a39f2f0b27c7fda5 \ --hash=sha256:f1c5efc278d996af8a251b2ce0b07bbeccb821f25c8c9846bdcb00ffc7f158aa \
--hash=sha256:9b03722c89a43a61d4d148acfc89ec5bb54cd0fd1539df25b10eb9c5fa6c393a \ --hash=sha256:eeb1859efe7754b1460e1d4991bbd4a60a56f366bc422ef3a9c5ae05f0bc70b5 \
--hash=sha256:2c2c5041608cb75c39cbd0ed05256f8a563e144234a524c59d091abbfa7a868f \ --hash=sha256:844a7b0233e4ff7fba57e90b8799edaa40b9e31e300b8d5efc350937fa8b1bea \
--hash=sha256:c092fc4673260b1446b8578015321081d5db73b94533fe4bf9b69f44e948d174 \ --hash=sha256:85f0c9cf724715e75243a7b3087cf4a3de056b55e05d4d76cc58d610d62894f3 \
--hash=sha256:27c9393fada62bd0ad7c730562a0fecbd3d5aaa8d9ed80ba7d3ebb8abc4f0453 \ --hash=sha256:c70b6311dda3e27672f1bf48851a0de816d1ca6aaf3d49365fbdd8e959b33d2b \
--hash=sha256:b8ba2a1dbb4660cb469fe8e1febb5119506059e675180c51396e1723ff9b79d9 \ --hash=sha256:b884715a59fec9ad3b6048ecf3860f3b2ce965e676ef52593d6fa29abcf7d330 \
--hash=sha256:0caa687fce6174fef9b27d45f8cc57cbc572e04e98c81db8e628b12b563d59a2 \ --hash=sha256:a78a3b51f29448c7f4d4575e561f6b0dbb8d01c13c2046ab6c5220eb25c06506 \
--hash=sha256:b7b09c61a91b742cb5460b72efd1fe26ef83c1c704f666e0af0df156b046aada \ --hash=sha256:6a724e3a48a54b8b6e7c4ae38cd3d07084508fa47c410c8757e9db9791421838 \
--hash=sha256:6ffd2d80d76df2e5f9f0c0140b5af97e3b87dd29852dcdb103ec177d853ec06b \ --hash=sha256:48e1e0859b54d5f2e29bb78ca179fd59b971c6ceb29977fb52735bfd280eb0f5 \
--hash=sha256:5111d6d47a0f5b8f3e10af7a79d5e7eb7e73a22825391834734274c4f312a8a0 \ --hash=sha256:01c9de93a2ca0d128c9064f23709362e7fefb34910c7c9e0b8ab0de8258d5eda \
--hash=sha256:a4fe54eab2c7129add75154823e6543b10261f9b65b2abe692d68743a4999f8c \ --hash=sha256:ebfb01a65c3f5d53a8c2a8133fec2b5221281c053d944ae81ff5822a68266617 \
--hash=sha256:83e6c895d93fdf93eeff1a21ee96778ba65ef258e5d284160f7c628fee40c38f \ --hash=sha256:b8b53f336a4688cfce615887505d7e41fd79b3594bf21dd300531a4f5b4f746a \
--hash=sha256:b26c472847911f5a7eb49e1c888c31c77c4ddf8023c1545e0e8e0367ba74fb15 \ --hash=sha256:fcd6f1954943c0c192bfbebbac263f839d7055409f1173f80d8b11a224d236da \
--hash=sha256:09225edca87a79815822eb7d3be63a83ebd4d9d98d5aa3a15a94f4eee2435954 \ --hash=sha256:6be8df61b1626e1a142c57e065405e869e9429b4a6dab4a324757d0dc4d42235 \
--hash=sha256:eb6b6700ea454bb88333d98601e74928e06f9669c1ea231b4c4c666c1d7701b4 \ --hash=sha256:41b6e307458988891fcdea2d8ecf84a8c92d53f84190aa32da65f9505546e684 \
--hash=sha256:2d31aff0c8184b05006ad756b9a4dc2a0805e94d28f3abc3187e881b6673b302 \ --hash=sha256:f72657f1596199dc1e4e7a10f52a4784ead8a711f4e5b59bea95bdb97cf0e4fd \
--hash=sha256:d082f77b4ed876ae94a9373f0db96bf8768a7cca6c58fc3038f94e30ffde1880 \ --hash=sha256:f15edcb0629a0801738925fe27070480f446fcaa15de65946ff946ad99a59a40 \
--hash=sha256:e71cdd402047e657c1662073e9361106c6981e9621ab8c249388dfc3ec1de07b \ --hash=sha256:556965514b259204637c360d213de28d43a1f4aed1eca15596ce83f768c5a56f \
--hash=sha256:756ee498b9ba35460e4cbbd73f09018e906daa8537fff61da5b5bf8d5e9de5c7 \ --hash=sha256:54a026055d5f8614f184e588f6e29064019a0aa8448450214c0b60926d62d919 \
--hash=sha256:7ad44f2c74c50567c694ee91c6fa16d67e7c8af6f22c656b80469ad927688457 \ --hash=sha256:fc4f526dfdb31c9bd6b8ca06bf9fab663ca12f3ec9cdf4496fb44bc680140318
--hash=sha256:3a4c3e9be63adf8e9b305aa58fb3ec40ecc61fd0f8fd3328ce55bc30e7a2aeb0 \ numpy==1.21.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:746897fbd72bd462b888c74ed35d812ca76006b04f717cd44698cdfc99aca70d \ --hash=sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50 \
--hash=sha256:5ed3d3342698c2b1f3651f8ea6c099b0f196d16ee00e33dc3a6fee8cb01d530a \ --hash=sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a \
--hash=sha256:b1b60c6476c4cfe9e5cf8ab0d3127476fd3d5f05de0f343a452badaad0e4bdec --hash=sha256:a75b4498b1e93d8b700282dc8e655b8bd559c0904b3910b144646dbbbc03e062 \
numpy==1.19.5; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:1412aa0aec3e00bc23fbb8664d76552b4efde98fb71f60737c83efbac24112f1 \
--hash=sha256:cc6bd4fd593cb261332568485e20a0712883cf631f6f5e8e86a52caa8b2b50ff \ --hash=sha256:e46ceaff65609b5399163de5893d8f2a82d3c77d5e56d976c8b5fb01faa6b671 \
--hash=sha256:aeb9ed923be74e659984e321f609b9ba54a48354bfd168d21a2b072ed1e833ea \ --hash=sha256:c6a2324085dd52f96498419ba95b5777e40b6bcbc20088fddb9e8cbb58885e8e \
--hash=sha256:8b5e972b43c8fc27d56550b4120fe6257fdc15f9301914380b27f74856299fea \ --hash=sha256:73101b2a1fef16602696d133db402a7e7586654682244344b8329cdcbbb82172 \
--hash=sha256:43d4c81d5ffdff6bae58d66a3cd7f54a7acd9a0e7b18d97abb255defc09e3140 \ --hash=sha256:7a708a79c9a9d26904d1cca8d383bf869edf6f8e7650d85dbc77b041e8c5a0f8 \
--hash=sha256:a4646724fba402aa7504cd48b4b50e783296b5e10a524c7a6da62e4a8ac9698d \ --hash=sha256:95b995d0c413f5d0428b3f880e8fe1660ff9396dcd1f9eedbc311f37b5652e16 \
--hash=sha256:2e55195bc1c6b705bfd8ad6f288b38b11b1af32f3c8289d6c50d47f950c12e76 \ --hash=sha256:635e6bd31c9fb3d475c8f44a089569070d10a9ef18ed13738b03049280281267 \
--hash=sha256:39b70c19ec771805081578cc936bbe95336798b7edf4732ed102e7a43ec5c07a \ --hash=sha256:4a3d5fb89bfe21be2ef47c0614b9c9c707b7362386c9a3ff1feae63e0267ccb6 \
--hash=sha256:dbd18bcf4889b720ba13a27ec2f2aac1981bd41203b3a3b27ba7a33f88ae4827 \ --hash=sha256:8a326af80e86d0e9ce92bcc1e65c8ff88297de4fa14ee936cb2293d414c9ec63 \
--hash=sha256:603aa0706be710eea8884af807b1b3bc9fb2e49b9f4da439e76000f3b3c6ff0f \ --hash=sha256:791492091744b0fe390a6ce85cc1bf5149968ac7d5f0477288f78c89b385d9af \
--hash=sha256:cae865b1cae1ec2663d8ea56ef6ff185bad091a5e33ebbadd98de2cfa3fa668f \ --hash=sha256:0318c465786c1f63ac05d7c4dbcecd4d2d7e13f0959b01b534ea1e92202235c5 \
--hash=sha256:36674959eed6957e61f11c912f71e78857a8d0604171dfd9ce9ad5cbf41c511c \ --hash=sha256:9a513bd9c1551894ee3d31369f9b07460ef223694098cf27d399513415855b68 \
--hash=sha256:06fab248a088e439402141ea04f0fffb203723148f6ee791e9c75b3e9e82f080 \ --hash=sha256:91c6f5fc58df1e0a3cc0c3a717bb3308ff850abdaa6d2d802573ee2b11f674a8 \
--hash=sha256:6149a185cece5ee78d1d196938b2a8f9d09f5a5ebfbba66969302a778d5ddd1d \ --hash=sha256:978010b68e17150db8765355d1ccdd450f9fc916824e8c4e35ee620590e234cd \
--hash=sha256:50a4a0ad0111cc1b71fa32dedd05fa239f7fb5a43a40663269bb5dc7877cfd28 \ --hash=sha256:9749a40a5b22333467f02fe11edc98f022133ee1bfa8ab99bda5e5437b831214 \
--hash=sha256:d051ec1c64b85ecc69531e1137bb9751c6830772ee5c1c426dbcfe98ef5788d7 \ --hash=sha256:d7a4aeac3b94af92a9373d6e77b37691b86411f9745190d2c351f410ab3a791f \
--hash=sha256:a12ff4c8ddfee61f90a1633a4c4afd3f7bcb32b11c52026c92a12e1325922d0d \ --hash=sha256:d9e7912a56108aba9b31df688a4c4f5cb0d9d3787386b87d504762b6754fbb1b \
--hash=sha256:cf2402002d3d9f91c8b01e66fbb436a4ed01c6498fffed0e4c7566da1d40ee1e \ --hash=sha256:25b40b98ebdd272bc3020935427a4530b7d60dfbe1ab9381a39147834e985eac \
--hash=sha256:1ded4fce9cfaaf24e7a0ab51b7a87be9038ea1ace7f34b841fe3b6894c721d1c \ --hash=sha256:8a92c5aea763d14ba9d6475803fc7904bda7decc2a0a68153f587ad82941fec1 \
--hash=sha256:012426a41bc9ab63bb158635aecccc7610e3eff5d31d1eb43bc099debc979d94 \ --hash=sha256:05a0f648eb28bae4bcb204e6fd14603de2908de982e761a2fc78efe0f19e96e1 \
--hash=sha256:759e4095edc3c1b3ac031f34d9459fa781777a93ccc633a472a5468587a190ff \ --hash=sha256:f01f28075a92eede918b965e86e8f0ba7b7797a95aa8d35e1cc8821f5fc3ad6a \
--hash=sha256:a9d17f2be3b427fbb2bce61e596cf555d6f8a56c222bd2ca148baeeb5e5c783c \ --hash=sha256:88c0b89ad1cc24a5efbb99ff9ab5db0f9a86e9cc50240177a571fbe9c2860ac2 \
--hash=sha256:99abf4f353c3d1a0c7a5f27699482c987cf663b1eac20db59b8c7b061eabd7fc \ --hash=sha256:01721eefe70544d548425a07c80be8377096a54118070b8a62476866d5208e33 \
--hash=sha256:384ec0463d1c2671170901994aeb6dce126de0a95ccc3976c43b0038a37329c2 \ --hash=sha256:2d4d1de6e6fb3d28781c73fbde702ac97f03d79e4ffd6598b880b2d95d62ead4 \
--hash=sha256:811daee36a58dc79cf3d8bdd4a490e4277d0e4b7d103a001a4e73ddb48e7e6aa \ --hash=sha256:dff4af63638afcc57a3dfb9e4b26d434a7a602d225b42d746ea7fe2edf1342fd
--hash=sha256:c843b3f50d1ab7361ca4f0b3639bf691569493a56808a0b0c54a051d260b7dbd \
--hash=sha256:d6631f2e867676b13026e2846180e2c13c1e11289d67da08d71cacb2cd93d4aa \
--hash=sha256:7fb43004bce0ca31d8f13a6eb5e943fa73371381e53f7074ed21a4cb786c32f8 \
--hash=sha256:2ea52bd92ab9f768cc64a4c3ef8f4b2580a17af0a5436f6126b08efbd1838371 \
--hash=sha256:400580cbd3cff6ffa6293df2278c75aef2d58d8d93d3c5614cd67981dae68ceb \
--hash=sha256:df609c82f18c5b9f6cb97271f03315ff0dbe481a2a02e56aeb1b1a985ce38e60 \
--hash=sha256:ab83f24d5c52d60dbc8cd0528759532736b56db58adaa7b5f1f76ad551416a1e \
--hash=sha256:0eef32ca3132a48e43f6a0f5a82cb508f22ce5a3d6f67a8329c81c8e226d3f6e \
--hash=sha256:a0d53e51a6cb6f0d9082decb7a4cb6dfb33055308c4c44f53103c073f649af73 \
--hash=sha256:a76f502430dd98d7546e1ea2250a7360c065a5fdea52b2dffe8ae7180909b6f4
odfpy==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ odfpy==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0 \ --hash=sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0 \
--hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec --hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec
openpyxl==3.0.6; python_version >= "3.7" and python_full_version < "4.0.0" \ openpyxl==3.0.9; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:1a4b3869c2500b5c713e8e28341cdada49ecfcff1b10cd9006945f5bcefc090d \ --hash=sha256:8f3b11bd896a95468a4ab162fc4fcd260d46157155d1f8bfaabb99d88cfcf79f \
--hash=sha256:b229112b46e158b910a5d1b270b212c42773d39cab24e8db527f775b82afc041 --hash=sha256:40f568b9829bf9e446acfffce30250ac1fa39035124d55fc024025c41481c90f
packaging==20.8; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ packaging==21.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:24e0da08660a87484d1602c30bb4902d74816b6985b93de36926f5bc95741858 \ --hash=sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14 \
--hash=sha256:78598185a7008a470d64526a8059de9aaa449238f280fc9eb6b13ba6c4109093 --hash=sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7
pillow==8.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ pillow==8.3.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:d355502dce85ade85a2511b40b4c61a128902f246504f7de29bbeec1ae27933a \ --hash=sha256:c691b26283c3a31594683217d746f1dad59a7ae1d4cfc24626d7a064a11197d4 \
--hash=sha256:93a473b53cc6e0b3ce6bf51b1b95b7b1e7e6084be3a07e40f79b42e83503fbf2 \ --hash=sha256:f514c2717012859ccb349c97862568fdc0479aad85b0270d6b5a6509dbc142e2 \
--hash=sha256:2353834b2c49b95e1313fb34edf18fca4d57446675d05298bb694bca4b194174 \ --hash=sha256:be25cb93442c6d2f8702c599b51184bd3ccd83adebd08886b682173e09ef0c3f \
--hash=sha256:1d208e670abfeb41b6143537a681299ef86e92d2a3dac299d3cd6830d5c7bded \ --hash=sha256:d675a876b295afa114ca8bf42d7f86b5fb1298e1b6bb9a24405a3f6c8338811c \
--hash=sha256:dd9eef866c70d2cbbea1ae58134eaffda0d4bfea403025f4db6859724b18ab3d \ --hash=sha256:59697568a0455764a094585b2551fd76bfd6b959c9f92d4bdec9d0e14616303a \
--hash=sha256:b09e10ec453de97f9a23a5aa5e30b334195e8d2ddd1ce76cc32e52ba63c8b31d \ --hash=sha256:2d5e9dc0bf1b5d9048a94c48d0813b6c96fccfa4ccf276d9c36308840f40c228 \
--hash=sha256:b02a0b9f332086657852b1f7cb380f6a42403a6d9c42a4c34a561aa4530d5234 \ --hash=sha256:11c27e74bab423eb3c9232d97553111cc0be81b74b47165f07ebfdd29d825875 \
--hash=sha256:ca20739e303254287138234485579b28cb0d524401f83d5129b5ff9d606cb0a8 \ --hash=sha256:11eb7f98165d56042545c9e6db3ce394ed8b45089a67124298f0473b29cb60b2 \
--hash=sha256:604815c55fd92e735f9738f65dabf4edc3e79f88541c221d292faec1904a4b17 \ --hash=sha256:2f23b2d3079522fdf3c09de6517f625f7a964f916c956527bed805ac043799b8 \
--hash=sha256:cf6e33d92b1526190a1de904df21663c46a456758c0424e4f947ae9aa6088bf7 \ --hash=sha256:19ec4cfe4b961edc249b0e04b5618666c23a83bc35842dea2bfd5dfa0157f81b \
--hash=sha256:47c0d93ee9c8b181f353dbead6530b26980fe4f5485aa18be8f1fd3c3cbc685e \ --hash=sha256:e5a31c07cea5edbaeb4bdba6f2b87db7d3dc0f446f379d907e51cc70ea375629 \
--hash=sha256:96d4dc103d1a0fa6d47c6c55a47de5f5dafd5ef0114fa10c85a1fd8e0216284b \ --hash=sha256:15ccb81a6ffc57ea0137f9f3ac2737ffa1d11f786244d719639df17476d399a7 \
--hash=sha256:7916cbc94f1c6b1301ac04510d0881b9e9feb20ae34094d3615a8a7c3db0dcc0 \ --hash=sha256:8f284dc1695caf71a74f24993b7c7473d77bc760be45f776a2c2f4e04c170550 \
--hash=sha256:3de6b2ee4f78c6b3d89d184ade5d8fa68af0848f9b6b6da2b9ab7943ec46971a \ --hash=sha256:4abc247b31a98f29e5224f2d31ef15f86a71f79c7f4d2ac345a5d551d6393073 \
--hash=sha256:cdbbe7dff4a677fb555a54f9bc0450f2a21a93c5ba2b44e09e54fcb72d2bd13d \ --hash=sha256:a048dad5ed6ad1fad338c02c609b862dfaa921fcd065d747194a6805f91f2196 \
--hash=sha256:f50e7a98b0453f39000619d845be8b06e611e56ee6e8186f7f60c3b1e2f0feae \ --hash=sha256:06d1adaa284696785375fa80a6a8eb309be722cf4ef8949518beb34487a3df71 \
--hash=sha256:cb192176b477d49b0a327b2a5a4979552b7a58cd42037034316b8018ac3ebb59 \ --hash=sha256:bd24054aaf21e70a51e2a2a5ed1183560d3a69e6f9594a4bfe360a46f94eba83 \
--hash=sha256:6c5275bd82711cd3dcd0af8ce0bb99113ae8911fc2952805f1d012de7d600a4c \ --hash=sha256:27a330bf7014ee034046db43ccbb05c766aa9e70b8d6c5260bfc38d73103b0ba \
--hash=sha256:165c88bc9d8dba670110c689e3cc5c71dbe4bfb984ffa7cbebf1fac9554071d6 \ --hash=sha256:13654b521fb98abdecec105ea3fb5ba863d1548c9b58831dd5105bb3873569f1 \
--hash=sha256:5e2fe3bb2363b862671eba632537cd3a823847db4d98be95690b7e382f3d6378 \ --hash=sha256:a1bd983c565f92779be456ece2479840ec39d386007cd4ae83382646293d681b \
--hash=sha256:7612520e5e1a371d77e1d1ca3a3ee6227eef00d0a9cddb4ef7ecb0b7396eddf7 \ --hash=sha256:4326ea1e2722f3dc00ed77c36d3b5354b8fb7399fb59230249ea6d59cbed90da \
--hash=sha256:d673c4990acd016229a5c1c4ee8a9e6d8f481b27ade5fc3d95938697fa443ce0 \ --hash=sha256:085a90a99404b859a4b6c3daa42afde17cb3ad3115e44a75f0d7b4a32f06a6c9 \
--hash=sha256:dc577f4cfdda354db3ae37a572428a90ffdbe4e51eda7849bf442fb803f09c9b \ --hash=sha256:18a07a683805d32826c09acfce44a90bf474e6a66ce482b1c7fcd3757d588df3 \
--hash=sha256:22d070ca2e60c99929ef274cfced04294d2368193e935c5d6febfd8b601bf865 \ --hash=sha256:4e59e99fd680e2b8b11bbd463f3c9450ab799305d5f2bafb74fefba6ac058616 \
--hash=sha256:a3d3e086474ef12ef13d42e5f9b7bbf09d39cf6bd4940f982263d6954b13f6a9 \ --hash=sha256:4d89a2e9219a526401015153c0e9dd48319ea6ab9fe3b066a20aa9aee23d9fd3 \
--hash=sha256:731ca5aabe9085160cf68b2dbef95fc1991015bc0a3a6ea46a371ab88f3d0913 \ --hash=sha256:56fd98c8294f57636084f4b076b75f86c57b2a63a8410c0cd172bc93695ee979 \
--hash=sha256:bba80df38cfc17f490ec651c73bb37cd896bc2400cfba27d078c2135223c1206 \ --hash=sha256:2b11c9d310a3522b0fd3c35667914271f570576a0e387701f370eb39d45f08a4 \
--hash=sha256:c3d911614b008e8a576b8e5303e3db29224b455d3d66d1b2848ba6ca83f9ece9 \ --hash=sha256:0412516dcc9de9b0a1e0ae25a280015809de8270f134cc2c1e32c4eeb397cf30 \
--hash=sha256:39725acf2d2e9c17356e6835dccebe7a697db55f25a09207e38b835d5e1bc032 \ --hash=sha256:bcb04ff12e79b28be6c9988f275e7ab69f01cc2ba319fb3114f87817bb7c74b6 \
--hash=sha256:81c3fa9a75d9f1afafdb916d5995633f319db09bd773cb56b8e39f1e98d90820 \ --hash=sha256:0b9911ec70731711c3b6ebcde26caea620cbdd9dcb73c67b0730c8817f24711b \
--hash=sha256:b6f00ad5ebe846cc91763b1d0c6d30a8042e02b2316e27b05de04fa6ec831ec5 \ --hash=sha256:ce2e5e04bb86da6187f96d7bab3f93a7877830981b37f0287dd6479e27a10341 \
--hash=sha256:887668e792b7edbfb1d3c9d8b5d8c859269a0f0eba4dda562adb95500f60dbba --hash=sha256:35d27687f027ad25a8d0ef45dd5208ef044c588003cdcedf05afb00dbc5c2deb \
--hash=sha256:04835e68ef12904bc3e1fd002b33eea0779320d4346082bd5b24bec12ad9c3e9 \
--hash=sha256:10e00f7336780ca7d3653cf3ac26f068fa11b5a96894ea29a64d3dc4b810d630 \
--hash=sha256:2cde7a4d3687f21cffdf5bb171172070bb95e02af448c4c8b2f223d783214056 \
--hash=sha256:1c3ff00110835bdda2b1e2b07f4a2548a39744bb7de5946dc8e95517c4fb2ca6 \
--hash=sha256:35d409030bf3bd05fa66fb5fdedc39c521b397f61ad04309c90444e893d05f7d \
--hash=sha256:6bff50ba9891be0a004ef48828e012babaaf7da204d81ab9be37480b9020a82b \
--hash=sha256:7dbfbc0020aa1d9bc1b0b8bcf255a7d73f4ad0336f8fd2533fcc54a4ccfb9441 \
--hash=sha256:963ebdc5365d748185fdb06daf2ac758116deecb2277ec5ae98139f93844bc09 \
--hash=sha256:cc9d0dec711c914ed500f1d0d3822868760954dce98dfb0b7382a854aee55d19 \
--hash=sha256:2c661542c6f71dfd9dc82d9d29a8386287e82813b0375b3a02983feac69ef864 \
--hash=sha256:548794f99ff52a73a156771a0402f5e1c35285bd981046a502d7e4793e8facaa \
--hash=sha256:8b68f565a4175e12e68ca900af8910e8fe48aaa48fd3ca853494f384e11c8bcd \
--hash=sha256:838eb85de6d9307c19c655c726f8d13b8b646f144ca6b3771fa62b711ebf7624 \
--hash=sha256:feb5db446e96bfecfec078b943cc07744cc759893cef045aa8b8b6d6aaa8274e \
--hash=sha256:fc0db32f7223b094964e71729c0361f93db43664dd1ec86d3df217853cedda87 \
--hash=sha256:fd4fd83aa912d7b89b4b4a1580d30e2a4242f3936882a3f433586e5ab97ed0d5 \
--hash=sha256:d0c8ebbfd439c37624db98f3877d9ed12c137cadd99dde2d2eae0dab0bbfc355 \
--hash=sha256:6cb3dd7f23b044b0737317f892d399f9e2f0b3a02b22b2c692851fb8120d82c6 \
--hash=sha256:a66566f8a22561fc1a88dc87606c69b84fa9ce724f99522cf922c801ec68f5c1 \
--hash=sha256:ce651ca46d0202c302a535d3047c55a0131a720cf554a578fc1b8a2aff0e7d96 \
--hash=sha256:dde3f3ed8d00c72631bc19cbfff8ad3b6215062a5eed402381ad365f82f0c18c
pprintpp==0.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \ pprintpp==0.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \ --hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403 --hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
psycopg2-binary==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \ psycopg2==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.4.0") \
--hash=sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0 \ --hash=sha256:068115e13c70dc5982dfc00c5d70437fe37c014c808acce119b5448361c03725 \
--hash=sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4 \ --hash=sha256:d160744652e81c80627a909a0e808f3c6653a40af435744de037e3172cf277f5 \
--hash=sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db \ --hash=sha256:b8cae8b2f022efa1f011cc753adb9cbadfa5a184431d09b273fb49b4167561ad \
--hash=sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5 \ --hash=sha256:f22ea9b67aea4f4a1718300908a2fb62b3e4276cf00bd829a97ab5894af42ea3 \
--hash=sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25 \ --hash=sha256:26e7fd115a6db75267b325de0fba089b911a4a12ebd3d0b5e7acb7028bc46821 \
--hash=sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c \ --hash=sha256:00195b5f6832dbf2876b8bf77f12bdce648224c89c880719c745b90515233301 \
--hash=sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c \ --hash=sha256:a49833abfdede8985ba3f3ec641f771cca215479f41523e99dace96d5b8cce2a \
--hash=sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1 \ --hash=sha256:f974c96fca34ae9e4f49839ba6b78addf0346777b46c4da27a7bf54f48d3057d \
--hash=sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2 \ --hash=sha256:6a3d9efb6f36f1fe6aa8dbb5af55e067db802502c55a9defa47c5a1dad41df84 \
--hash=sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152 \ --hash=sha256:56fee7f818d032f802b8eed81ef0c1232b8b42390df189cab9cfa87573fe52c5 \
--hash=sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449 \ --hash=sha256:ad2fe8a37be669082e61fb001c185ffb58867fdbb3e7a6b0b0d2ffe232353a3e \
--hash=sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859 \ --hash=sha256:56007a226b8e95aa980ada7abdea6b40b75ce62a433bd27cec7a8178d57f4051 \
--hash=sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550 \ --hash=sha256:2c93d4d16933fea5bbacbe1aaf8fa8c1348740b2e50b3735d1b0bf8154cbf0f3 \
--hash=sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd \ --hash=sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7 \
--hash=sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71 \ --hash=sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543
--hash=sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4 \ pyparsing==2.4.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.3.0" \
--hash=sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb \
--hash=sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da \
--hash=sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2 \
--hash=sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a \
--hash=sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679 \
--hash=sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf \
--hash=sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b \
--hash=sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67 \
--hash=sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66 \
--hash=sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f \
--hash=sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77 \
--hash=sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94 \
--hash=sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729 \
--hash=sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77 \
--hash=sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83 \
--hash=sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52 \
--hash=sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd \
--hash=sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056 \
--hash=sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6
pyparsing==2.4.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \
--hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
--hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1
python-dateutil==2.8.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.3.0" \ python-dateutil==2.8.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.3.0" \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
python-stdnum==1.15; python_version >= "3.7" and python_full_version < "4.0.0" \ pytz==2021.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:ff0e4d2b8731711cf2a73d22964139208088b4bd1a3e3b0c4f78d6e823dd8923 \ --hash=sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c \
--hash=sha256:46c05dff2d5ff89b12cc63ab54cca1e4788e4e3087c163a1b7434a53fa926f28 --hash=sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326
pytz==2020.5; python_version >= "3.7" and python_full_version < "4.0.0" \ pyyaml==5.4.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4 \ --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
--hash=sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5 --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
pyyaml==5.3.1; python_version >= "3.7" and python_full_version < "4.0.0" \ --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
--hash=sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f \ --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
--hash=sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76 \ --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
--hash=sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2 \ --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
--hash=sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c \ --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
--hash=sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2 \ --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
--hash=sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648 \ --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
--hash=sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a \ --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
--hash=sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf \ --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
--hash=sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97 \ --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
--hash=sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee \ --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
--hash=sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
--hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
--hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
--hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
--hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
--hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
--hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
--hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e
redis==3.5.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ redis==3.5.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \
--hash=sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24 \ --hash=sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24 \
--hash=sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2 --hash=sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2
requests==2.25.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ requests==2.26.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e \ --hash=sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 --hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
six==1.15.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ six==1.16.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.3.0" \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926
sqlparse==0.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ sqlparse==0.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \ --hash=sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d \
--hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8 --hash=sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae
svgwrite==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ svgwrite==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4b21652a1d9c543a6bf4f9f2a54146b214519b7540ca60cb99968ad09ef631d0 \ --hash=sha256:4b21652a1d9c543a6bf4f9f2a54146b214519b7540ca60cb99968ad09ef631d0 \
--hash=sha256:e220a4bf189e7e214a55e8a11421d152b5b6fb1dd660c86a8b6b61fe8cc2ac48 --hash=sha256:e220a4bf189e7e214a55e8a11421d152b5b6fb1dd660c86a8b6b61fe8cc2ac48
tablib==3.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \ tablib==3.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:41aa40981cddd7ec4d1fabeae7c38d271601b306386bd05b5c3bcae13e5aeb20 \ --hash=sha256:41aa40981cddd7ec4d1fabeae7c38d271601b306386bd05b5c3bcae13e5aeb20 \
--hash=sha256:f83cac08454f225a34a305daa20e2110d5e6335135d505f93bc66583a5f9c10d --hash=sha256:f83cac08454f225a34a305daa20e2110d5e6335135d505f93bc66583a5f9c10d
urllib3==1.26.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version < "4" and python_version >= "3.7" and python_full_version < "4.0.0" \ typing-extensions==3.10.0.2; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473 \ --hash=sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7 \
--hash=sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08 --hash=sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34 \
webencodings==0.5.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ --hash=sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e
urllib3==1.26.7; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844 \
--hash=sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece
webencodings==0.5.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
xlrd==2.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \ xlrd==2.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
@ -351,3 +375,6 @@ xlrd==2.0.1; python_version >= "3.7" and python_full_version < "3.0.0" or python
xlwt==1.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \ xlwt==1.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \ --hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \
--hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88 --hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88
zipp==3.6.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc \
--hash=sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832

View file

@ -11,7 +11,8 @@
from pathlib import Path as __Path from pathlib import Path as __Path
from django_ynh.secret_key import get_or_create_secret as __get_or_create_secret from django_yunohost_integration.base_settings import * # noqa
from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret
from for_runners_project.settings.base import * # noqa from for_runners_project.settings.base import * # noqa
@ -40,12 +41,12 @@ YNH_SETUP_USER = 'setup_user.setup_project_user'
SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt
INSTALLED_APPS.append('django_ynh') INSTALLED_APPS.append('django_yunohost_integration')
MIDDLEWARE.insert( MIDDLEWARE.insert(
MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1, MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
# login a user via HTTP_REMOTE_USER header from SSOwat: # login a user via HTTP_REMOTE_USER header from SSOwat:
'django_ynh.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware', 'django_yunohost_integration.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware',
) )
# Keep ModelBackend around for per-user permissions and superuser # Keep ModelBackend around for per-user permissions and superuser
@ -53,7 +54,7 @@ AUTHENTICATION_BACKENDS = (
'axes.backends.AxesBackend', # AxesBackend should be the first backend! 'axes.backends.AxesBackend', # AxesBackend should be the first backend!
# #
# Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header: # Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header:
'django_ynh.sso_auth.auth_backend.SSOwatUserBackend', 'django_yunohost_integration.sso_auth.auth_backend.SSOwatUserBackend',
# #
# Fallback to normal Django model backend: # Fallback to normal Django model backend:
'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend',
@ -109,7 +110,7 @@ CACHES = {
'default': { 'default': {
'BACKEND': 'django_redis.cache.RedisCache', 'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/__REDIS_DB__', 'LOCATION': 'redis://127.0.0.1:6379/__REDIS_DB__',
# If redis is running on same host as Django-ForRunners, you might # If redis is running on same host as django-for-runners, you might
# want to use unix sockets instead: # want to use unix sockets instead:
# 'LOCATION': 'unix:///var/run/redis/redis.sock?db=1', # 'LOCATION': 'unix:///var/run/redis/redis.sock?db=1',
'OPTIONS': { 'OPTIONS': {

View file

@ -1,7 +1,7 @@
def setup_project_user(user): def setup_project_user(user):
""" """
All users used the Django admin, so we need to set the "staff" user flag. All users used the Django admin, so we need to set the "staff" user flag.
Called from django_ynh.sso_auth Called from django_yunohost_integration.sso_auth
""" """
user.is_staff = True user.is_staff = True
user.save() user.save()

View file

@ -4,11 +4,29 @@ from django.contrib import admin
from django.urls import path from django.urls import path
# def debug_view(request):
# """ debug request.META """
# if not request.user.is_authenticated:
# from django.shortcuts import redirect
# return redirect('admin:index')
#
# import pprint
# meta = pprint.pformat(request.META)
# html = f'<html><body>request.META: <pre>{meta}</pre></body></html>'
# from django.http import HttpResponse
# return HttpResponse(html)
if settings.PATH_URL: if settings.PATH_URL:
# settings.PATH_URL is the $YNH_APP_ARG_PATH # settings.PATH_URL is the $YNH_APP_ARG_PATH
# Prefix all urls with "PATH_URL": # Prefix all urls with "PATH_URL":
urlpatterns = [ urlpatterns = [
# path(f'{settings.PATH_URL}/debug/', debug_view),
path(f'{settings.PATH_URL}/', admin.site.urls), path(f'{settings.PATH_URL}/', admin.site.urls),
# TODO: https://github.com/jedie/django-for-runners/issues/25
# MEDIA_URL contains the "PATH_URL" already:
# path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')),
] ]
if settings.SERVE_FILES: if settings.SERVE_FILES:
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

View file

@ -10,7 +10,7 @@ from pathlib import Path
try: try:
from django_ynh.local_test import create_local_test from django_yunohost_integration.local_test import create_local_test
except ImportError as err: except ImportError as err:
raise ImportError('Did you forget to activate a virtual environment?') from err raise ImportError('Did you forget to activate a virtual environment?') from err

View file

@ -1,5 +1,5 @@
{ {
"name": "Django-ForRunners", "name": "django-for-runners",
"id": "django-for-runners", "id": "django-for-runners",
"packaging_format": 1, "packaging_format": 1,
"description": { "description": {
@ -26,8 +26,8 @@
"name": "domain", "name": "domain",
"type": "domain", "type": "domain",
"ask": { "ask": {
"en": "Choose a domain for Django-ForRunners", "en": "Choose a domain for django-for-runners",
"fr": "Choisissez un domaine pour Django-ForRunners" "fr": "Choisissez un domaine pour django-for-runners"
}, },
"example": "domain.org" "example": "domain.org"
}, },
@ -35,8 +35,8 @@
"name": "path", "name": "path",
"type": "path", "type": "path",
"ask": { "ask": {
"en": "Choose a path for Django-ForRunners", "en": "Choose a path for django-for-runners",
"fr": "Choisissez un chemin pour Django-ForRunners" "fr": "Choisissez un chemin pour django-for-runners"
}, },
"example": "/django-for-runners", "example": "/django-for-runners",
"default": "/django-for-runners" "default": "/django-for-runners"
@ -45,23 +45,10 @@
"name": "admin", "name": "admin",
"type": "user", "type": "user",
"ask": { "ask": {
"en": "Choose an admin user for Django-ForRunners", "en": "Choose an admin user for django-for-runners",
"fr": "Choisissez l'administrateur pour Django-ForRunners" "fr": "Choisissez l'administrateur pour django-for-runners"
}, },
"example": "johndoe" "example": "johndoe"
},
{
"name": "is_public",
"type": "boolean",
"ask": {
"en": "Should Django-ForRunners be public accessible?",
"fr": "Django-ForRunners doit-il être accessible au public ?"
},
"help": {
"en": "Any YunoHost user and anonymous people from the web will be able to access the application",
"fr": "Tout utilisateur YunoHost et les personnes anonymes pourront accéder à l'application"
},
"default": false
} }
] ]
} }

1272
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,23 @@
[tool.poetry] [tool.poetry]
name = "django-for-runners_ynh" name = "for_runners_ynh"
version = "0.12.0~ynh2" version = "0.12.0~ynh1"
description = "Test django-for-runners_ynh via local_test.py" description = "Test for_runners_ynh via local_test.py"
authors = ["JensDiemer <git@jensdiemer.de>"] authors = ["JensDiemer <git@jensdiemer.de>"]
license = "GPL" license = "GPL"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.7,<4.0.0" python = ">=3.7,<4.0.0"
django-for-runners = "==0.12.0" django-for-runners = "*"
django_ynh = "*" # Note: "ynh" extras will install gunicorn, psycopg2, django-redis and django-axes
gunicorn = "*" django_yunohost_integration = {version = ">=v0.2.0", extras = ["ynh"]}
psycopg2-binary = "*"
django-redis = "*"
#django-axes = "*" # https://github.com/jazzband/django-axes
# TODO: Update psycopg2 after django-for-runners updates Django >2.2 update
# See: https://github.com/psycopg/psycopg2/issues/1293
psycopg2 = "<2.9" # https://www.psycopg.org/docs/install.html#build-prerequisites
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
bx_py_utils = "*" bx_py_utils = "*"
bx_django_utils = "*"
tox = "*" tox = "*"
pytest = "*" pytest = "*"
pytest-cov = "*" pytest-cov = "*"
@ -41,7 +42,7 @@ case_sensitive=false
skip_glob=["*/htmlcov/*","*/migrations/*"] skip_glob=["*/htmlcov/*","*/migrations/*"]
multi_line_output=3 multi_line_output=3
include_trailing_comma=true include_trailing_comma=true
known_first_party=["inventory"] known_first_party=["for_runners"]
no_lines_before="LOCALFOLDER" no_lines_before="LOCALFOLDER"
default_section="THIRDPARTY" default_section="THIRDPARTY"
sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"] sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"]

View file

@ -6,7 +6,7 @@ from pathlib import Path
try: try:
from django_ynh.pytest_helper import run_pytest from django_yunohost_integration.pytest_helper import run_pytest
except ImportError as err: except ImportError as err:
raise ImportError('Did you forget to activate a virtual environment?') from err raise ImportError('Did you forget to activate a virtual environment?') from err

View file

@ -24,8 +24,17 @@ log_file="${log_path}/django-for-runners.log"
# COMMON VARIABLES # COMMON VARIABLES
#================================================= #=================================================
# dependencies used by the app # Needed base dependencies:
pkg_dependencies="build-essential python3-dev python3-pip python3-venv git postgresql postgresql-contrib" pkg_dependencies="build-essential python3-dev python3-pip python3-venv git"
# For pillow:
pkg_dependencies="${pkg_dependencies} libjpeg-dev"
# Postgres and Python's "psycopg2":
pkg_dependencies="${pkg_dependencies} libpq-dev postgresql postgresql-contrib"
# Needed for lxml: https://lxml.de/installation.html#requirements
pkg_dependencies="${pkg_dependencies} libxml2-dev libxslt-dev"
#================================================= #=================================================
# Redis HELPERS # Redis HELPERS

View file

@ -105,7 +105,7 @@ ynh_script_progression --message="Install project via pip..." --weight=80
python3 -m venv "${final_path}/venv" python3 -m venv "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app" "$final_path" chown -R "$app:" "$final_path"
#run source in a 'sub shell' #run source in a 'sub shell'
( (
@ -204,9 +204,9 @@ yunohost service add $app --description="Web based management to catalog things"
#================================================= #=================================================
# Set permissions to app files # Set permissions to app files
chown -R "$app" "$log_path" chown -R "$app:" "$log_path"
chown -R "$app" "$public_path" chown -R "$app:" "$public_path"
chown -R "$app" "$final_path" chown -R "$app:" "$final_path"
#================================================= #=================================================
# SETUP SYSTEMD # SETUP SYSTEMD
@ -214,23 +214,10 @@ chown -R "$app" "$final_path"
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring a systemd service..."
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd # https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd
ynh_add_systemd_config --service="$app" --template="for_runners.service" ynh_add_systemd_config --service="$app" --template="django-for-runners.service"
#================================================= #=================================================
# SETUP SSOWAT # Start for_runners via systemd
#=================================================
ynh_script_progression --message="Configuring SSOwat..."
# Make app public if necessary or protect it
if [ $is_public -eq 1 ]
then
# Everyone can access the app.
# The "main" permission is automatically created before the install script.
ynh_permission_update --permission "main" --add "visitors"
fi
#=================================================
# Start pyinventory via systemd
#================================================= #=================================================
ynh_script_progression --message="Starting project services..." --weight=5 ynh_script_progression --message="Starting project services..." --weight=5

View file

@ -70,8 +70,8 @@ ynh_system_user_create --username=$app --home_dir="$final_path" --use_shell
#================================================= #=================================================
# Restore permissions on app files # Restore permissions on app files
chown -R "$app" "$public_path" chown -R "$app:" "$public_path"
chown -R "$app" "$final_path" chown -R "$app:" "$final_path"
#================================================= #=================================================
# SPECIFIC RESTORATION # SPECIFIC RESTORATION
@ -82,6 +82,23 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=40
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies" ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
#=================================================
# REINSTALL PYTHON VIRTUALENV
# Maybe the backup contains a other Python version
#=================================================
ynh_script_progression --message="Upgrade Python virtualenv..." --weight=10
python3 -m venv --upgrade "${final_path}/venv"
#run source in a 'sub shell'
(
set +o nounset
source "${final_path}/venv/bin/activate"
set -o nounset
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade pip
ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt"
)
#================================================= #=================================================
# RESTORE THE PostgreSQL DATABASE # RESTORE THE PostgreSQL DATABASE
#================================================= #=================================================
@ -112,7 +129,7 @@ yunohost service add $app --description="Web based management to catalog things"
mkdir -p "$log_path" mkdir -p "$log_path"
touch "${log_file}" touch "${log_file}"
chown -R "$app" "$log_path" chown -R "$app:" "$log_path"
ynh_restore_file --origin_path="/etc/logrotate.d/$app" ynh_restore_file --origin_path="/etc/logrotate.d/$app"
#================================================= #=================================================

View file

@ -80,16 +80,16 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring a systemd service..."
ynh_add_systemd_config --service="$app" --template="for_runners.service" ynh_add_systemd_config --service="$app" --template="django-for-runners.service"
#================================================= #=================================================
# UPGRADE VENV # UPGRADE VENV
#================================================= #=================================================
ynh_script_progression --message="Upgrade project via pip..." --weight=80 ynh_script_progression --message="Upgrade project via pip..." --weight=80
python3 -m venv "${final_path}/venv" python3 -m venv --upgrade "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app" "$final_path" chown -R "$app:" "$final_path"
#run source in a 'sub shell' #run source in a 'sub shell'
( (
@ -196,12 +196,12 @@ yunohost service add $app --description="Web based management to catalog things"
#================================================= #=================================================
# Set permissions to app files # Set permissions to app files
chown -R "$app" "$log_path" chown -R "$app:" "$log_path"
chown -R "$app" "$public_path" chown -R "$app:" "$public_path"
chown -R "$app" "$final_path" chown -R "$app:" "$final_path"
#================================================= #=================================================
# Start pyinventory via systemd # Start for_runners via systemd
#================================================= #=================================================
ynh_script_progression --message="Starting project services..." --weight=5 ynh_script_progression --message="Starting project services..." --weight=5

View file

@ -1,14 +1,15 @@
import for_runners
from axes.models import AccessLog from axes.models import AccessLog
from bx_py_utils.test_utils.html_assertion import HtmlAssertionMixin from bx_django_utils.test_utils.html_assertion import HtmlAssertionMixin
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test import override_settings from django.test import override_settings
from django.test.testcases import TestCase from django.test.testcases import TestCase
from django.urls import NoReverseMatch from django.urls import NoReverseMatch
from django.urls.base import reverse from django.urls.base import reverse
from django_ynh.test_utils import generate_basic_auth from django_yunohost_integration.test_utils import generate_basic_auth
from django_ynh.views import request_media_debug_view from django_yunohost_integration.views import request_media_debug_view
import for_runners
@override_settings(DEBUG=False) @override_settings(DEBUG=False)
@ -24,7 +25,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
assert str(settings.FINAL_HOME_PATH).endswith('/local_test/opt_yunohost') assert str(settings.FINAL_HOME_PATH).endswith('/local_test/opt_yunohost')
assert str(settings.FINAL_WWW_PATH).endswith('/local_test/var_www') assert str(settings.FINAL_WWW_PATH).endswith('/local_test/var_www')
assert str(settings.LOG_FILE).endswith('/local_test/var_log_django-for-runners_ynh.log') assert str(settings.LOG_FILE).endswith('/local_test/var_log_django-for-runners.log')
assert settings.ROOT_URLCONF == 'urls' assert settings.ROOT_URLCONF == 'urls'
@ -43,9 +44,24 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
# ) # )
def test_auth(self): def test_auth(self):
response = self.client.get('/app_path/') # SecurityMiddleware should redirects all non-HTTPS requests to HTTPS:
self.assertRedirects(response, expected_url='/app_path/login/?next=/app_path/') assert settings.SECURE_SSL_REDIRECT is True
response = self.client.get('/app_path/', secure=False)
self.assertRedirects(
response,
status_code=301, # permanent redirect
expected_url='https://testserver/app_path/',
fetch_redirect_response=False
)
response = self.client.get('/app_path/', secure=True)
self.assertRedirects(
response,
expected_url='/app_path/login/?next=/app_path/',
fetch_redirect_response=False
)
@override_settings(SECURE_SSL_REDIRECT=False)
def test_create_unknown_user(self): def test_create_unknown_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
@ -65,6 +81,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler
assert user.is_superuser is False assert user.is_superuser is False
assert response.status_code == 200
self.assert_html_parts( self.assert_html_parts(
response, response,
parts=( parts=(
@ -73,6 +90,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
), ),
) )
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_auth_user(self): def test_wrong_auth_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
assert AccessLog.objects.count() == 0 assert AccessLog.objects.count() == 0
@ -97,6 +115,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
assert response.status_code == 403 # Forbidden assert response.status_code == 403 # Forbidden
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_cookie(self): def test_wrong_cookie(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
assert AccessLog.objects.count() == 0 assert AccessLog.objects.count() == 0
@ -121,6 +140,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
assert response.status_code == 403 # Forbidden assert response.status_code == 403 # Forbidden
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_authorization_user(self): def test_wrong_authorization_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0

View file

@ -1,8 +1,11 @@
import difflib
import os import os
import shutil import shutil
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from bx_py_utils.path import assert_is_file
import for_runners import for_runners
@ -21,21 +24,42 @@ def test_version():
version = for_runners.__version__ version = for_runners.__version__
assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh') assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh')
assert_file_contains_string(
file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'django-for-runners = "=={version}"'
)
assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh') assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh')
def test_poetry_check(): def poetry_check_output(*args):
poerty_bin = shutil.which('poetry') poerty_bin = shutil.which('poetry')
output = subprocess.check_output( output = subprocess.check_output(
[poerty_bin, 'check'], (poerty_bin,) + args,
universal_newlines=True, universal_newlines=True,
env=os.environ, env=os.environ,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
cwd=str(PACKAGE_ROOT), cwd=str(PACKAGE_ROOT),
) )
print(output) print(output)
return output
def test_poetry_check():
output = poetry_check_output('check')
assert output == 'All set!\n' assert output == 'All set!\n'
def test_requirements_txt():
requirements_txt = Path('conf', 'requirements.txt')
assert_is_file(requirements_txt)
output = poetry_check_output('export', '-f', 'requirements.txt')
assert 'Warning' not in output
current_content = requirements_txt.read_text()
diff = '\n'.join(
difflib.unified_diff(
current_content.splitlines(), output.splitlines(),
fromfile=str(requirements_txt), tofile='FRESH EXPORT'
)
)
print(diff)
assert diff == '', f'{requirements_txt} is not up-to-date! (Hint: call: "make update")'

View file

@ -1,6 +1,6 @@
from unittest.case import TestCase from unittest.case import TestCase
from django_ynh.test_utils import generate_basic_auth from django_yunohost_integration.test_utils import generate_basic_auth
class TestUtilsTestCase(TestCase): class TestUtilsTestCase(TestCase):