Merge pull request #20 from YunoHost-Apps/updates

Updates
This commit is contained in:
Jens Diemer 2022-04-15 17:00:29 +02:00 committed by GitHub
commit 25ccf0984c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 1516 additions and 992 deletions

View file

@ -14,7 +14,7 @@ jobs:
strategy:
max-parallel: 2
matrix:
python-version: [3.9, 3.8, 3.7]
python-version: ["3.10", "3.9", "3.8", "3.7"]
steps:
- uses: actions/checkout@v1
- name: 'Set up Python ${{ matrix.python-version }}'
@ -37,8 +37,3 @@ jobs:
- name: 'Upload coverage report'
run: bash <(curl -s https://codecov.io/bash)
- name: 'Run linters'
if: matrix.python-version == '3.8'
run: |
make lint

View file

@ -28,16 +28,6 @@ update: install-poetry ## update the sources and installation and generate "con
poetry update
poetry export -f requirements.txt --output conf/requirements.txt
lint: ## Run code formatters and linter
poetry run flynt --fail-on-change --line_length=${MAX_LINE_LENGTH} .
poetry run isort --check-only .
poetry run flake8 .
fix-code-style: ## Fix code formatting
poetry run flynt --line_length=${MAX_LINE_LENGTH} .
poetry run black --verbose --safe --line-length=${MAX_LINE_LENGTH} --skip-string-normalization .
poetry run isort .
tox-listenvs: check-poetry ## List all tox test environments
poetry run tox --listenvs

View file

@ -1,45 +1,49 @@
<!--
N.B.: This README was automatically generated by https://github.com/YunoHost/apps/tree/master/tools/README-generator
It shall NOT be edited by hand.
-->
# 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) [![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)
[![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)
[![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)
[![Install django-for-runners with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
*[Lire ce readme en français.](./README_fr.md)*
> *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.*
Pull requests welcome ;)
## Overview
![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/).
[![pytest](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](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)
![django-for-runners @ PyPi](https://img.shields.io/pypi/v/django-for-runners?label=django-for-runners%20%40%20PyPi)
![Python Versions](https://img.shields.io/pypi/pyversions/django-for-runners)
![License GPL V3+](https://img.shields.io/pypi/l/django-for-runners)
Pull requests welcome ;)
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
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)
**Shipped version:** 0.12.1~ynh1
## Screenshots
![](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png)
![](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png)
![](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.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)
----
![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)
## Disclaimers / important information
## Settings and upgrades
@ -193,3 +197,23 @@ Notes:
* SQlite database will be used
* A super user with username `test` and password `test` is created
* The page is available under `http://127.0.0.1:8000/app_path/`
## Documentation and resources
* Official app website: https://github.com/jedie/django-for-runners
* Upstream app code repository: https://github.com/jedie/django-for-runners
* YunoHost documentation for this app: https://yunohost.org/app_django-for-runners
* Report a bug: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues
## Developer info
Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing).
To try the testing branch, please proceed like that.
```
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
```
**More info regarding app packaging:** https://yunohost.org/packaging_apps

215
README_fr.md Normal file
View file

@ -0,0 +1,215 @@
# django-for-runners pour YunoHost
[![Niveau d'intégration](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)
[![Installer django-for-runners avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
*[Read this readme in english.](./README.md)*
*[Lire ce readme en français.](./README_fr.md)*
> *Ce package vous permet d'installer django-for-runners rapidement et simplement sur un serveur YunoHost.
Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.*
## Vue d'ensemble
![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/).
[![pytest](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](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)
![django-for-runners @ PyPi](https://img.shields.io/pypi/v/django-for-runners?label=django-for-runners%20%40%20PyPi)
![Python Versions](https://img.shields.io/pypi/pyversions/django-for-runners)
![License GPL V3+](https://img.shields.io/pypi/l/django-for-runners)
Pull requests welcome ;)
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
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)
**Version incluse :** 0.12.1~ynh1
## Captures d'écran
![](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png)
![](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png)
![](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png)
## Avertissements / informations importantes
## Settings and upgrades
Almost everything related to django-for-runners's configuration is handled in a `"../conf/settings.py"` file.
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
## SSO authentication
[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django_ynh](https://github.com/YunoHost-Apps/django_ynh):
* First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user
* All new users will be created as normal users
* Login via SSO is fully supported
* User Email, First / Last name will be updated from SSO data
## Links
* Report a bug about this package: https://github.com/YunoHost-Apps/django-for-runners_ynh
* Report a bug about django-for-runners itself: https://github.com/jedie/django-for-runners
* YunoHost website: https://yunohost.org/
---
# Developer info
## package installation / debugging
Please send your pull request to https://github.com/YunoHost-Apps/django-for-runners_ynh
Try 'main' branch, e.g.:
```bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/master --debug
or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/master --debug
```
Try 'testing' branch, e.g.:
```bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
```
To remove call e.g.:
```bash
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.:
```bash
root@yunohost:~# ls -la /var/www/django-for-runners/
total 18
drwxr-xr-x 4 root root 4 Dec 8 08:36 .
drwxr-xr-x 6 root root 6 Dec 8 08:36 ..
drwxr-xr-x 2 root root 2 Dec 8 08:36 media
drwxr-xr-x 7 root root 8 Dec 8 08:40 static
root@yunohost:~# ls -la /opt/yunohost/django-for-runners/
total 58
drwxr-xr-x 5 django-for-runners django-for-runners 11 Dec 8 08:39 .
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
-rw-r--r-- 1 django-for-runners django-for-runners 460 Dec 8 08:39 gunicorn.conf.py
-rw-r--r-- 1 django-for-runners django-for-runners 0 Dec 8 08:39 local_settings.py
-rwxr-xr-x 1 django-for-runners django-for-runners 274 Dec 8 08:39 manage.py
-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
-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 settings.py
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 check
django-for-runners v0.8.2 (Django v2.2.17)
DJANGO_SETTINGS_MODULE='settings'
PROJECT_PATH:/opt/yunohost/django-for-runners/venv/lib/python3.7/site-packages
BASE_PATH:/opt/yunohost/django-for-runners
System check identified no issues (0 silenced).
root@yunohost:~# tail -f /var/log/django-for-runners/django-for-runners.log
root@yunohost:~# cat /etc/systemd/system/django-for-runners.service
root@yunohost:~# systemctl reload-or-restart django-for-runners
root@yunohost:~# journalctl --unit=for_runners --follow
```
## local test
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
and urls made for YunoHost installation.
e.g.:
```bash
~$ git clone https://github.com/YunoHost-Apps/django-for-runners_ynh.git
~$ cd django-for-runners_ynh/
~/django-for-runners_ynh$ make
install-poetry install or update poetry
install install django-for-runners via poetry
update update the sources and installation
local-test Run local_test.py to run django-for-runners_ynh locally
~/django-for-runners_ynh$ make install-poetry
~/django-for-runners_ynh$ make install
~/django-for-runners_ynh$ make local-test
```
Notes:
* SQlite database will be used
* A super user with username `test` and password `test` is created
* The page is available under `http://127.0.0.1:8000/app_path/`
## Documentations et ressources
* Site officiel de l'app : https://github.com/jedie/django-for-runners
* Dépôt de code officiel de l'app : https://github.com/jedie/django-for-runners
* Documentation YunoHost pour cette app : https://yunohost.org/app_django-for-runners
* Signaler un bug : https://github.com/YunoHost-Apps/django-for-runners_ynh/issues
## Informations pour les développeurs
Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing).
Pour essayer la branche testing, procédez comme suit.
```
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
ou
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
```
**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps

View file

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!__FINAL_HOME_PATH__/venv/bin/python
import os
import sys

View file

@ -1,23 +1,26 @@
async-timeout==4.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15 \
--hash=sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c
autotask==0.5.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:d21578ab14adafb0d9be3490a444d261fd2bcdcbb1ee941b28d4b5e5d1a386ad
bleach==4.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994 \
--hash=sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da
bx-django-utils==11; python_version >= "3.6" and python_full_version < "4.0.0" \
--hash=sha256:b4115fbffb5b788e3ed6c13f5aa9d87991da35f1235de4376ca3e780d03546e9 \
--hash=sha256:a7549c6fd6b9a745e8949c6dfede825433d532c907e86140b7b8fb19cb63945c
bx-py-utils==50; python_version >= "3.6" and python_full_version < "4.0.0" \
--hash=sha256:3713ee75904c061eb934d2ab7a842760a8e0fb99db3b69ff5bd6841aa9ef04ae \
--hash=sha256:8799ffd2a12f5aff9654cafd486990ee1a3e5a7be4d00c35f6b0449843568316
bleach==5.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1 \
--hash=sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565
bx-django-utils==21; python_version >= "3.6" and python_full_version < "4.0.0" \
--hash=sha256:414ada254464b6db851a4eed20460e3d6d78c749459419cbadc7341019d69379 \
--hash=sha256:ccd90e09c5f334d848508b9ba0fe1857291548cfb49a41cc56d3c78744773951
bx-py-utils==61; python_version >= "3.6" and python_full_version < "4.0.0" \
--hash=sha256:8af6c2ab7396452f689441c4cf2ea2b26a7d3cc1349041e333ce441ca1c8261b \
--hash=sha256:34be9906ad6629d28e2d22290de575a4a600a49625455ec758c8b02adadb44f2
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:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569 \
--hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872
charset-normalizer==2.0.7; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0 \
--hash=sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b
click==8.0.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3 \
--hash=sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b
charset-normalizer==2.0.12; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
--hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \
--hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df
click==8.1.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:24e1a4a9ec5bf6299411369b208c1df2188d9eb8d916302fe6bf03faed227f1e \
--hash=sha256:479707fe14d9ec9a0757618b7a100a0ae4c4e236fac5b7f80ca68028141a1a72
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:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b
@ -41,39 +44,39 @@ django-axes==5.27.0; python_version >= "3.7" and python_version < "4.0" and pyth
--hash=sha256:e6ac2266626d4e52a44939bdb861817766f127efe110c8e8ce2a776270954926
django-dbbackup==3.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:bb109735cae98b64ad084e5b461b7aca2d7b39992f10c9ed9435e3ebb6fb76c8
django-debug-toolbar==3.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:8c5b13795d4040008ee69ba82dcdd259c49db346cf7d0de6e561a49d191f0860 \
--hash=sha256:d7bab7573fab35b0fd029163371b7182f5826c13da69734beb675c761d06a4d3
django-debug-toolbar==3.2.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9 \
--hash=sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409
django-for-runners==0.12.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:5efe6e8e7abaec9faf31cfe670b0e0b441877b00b0966b38d5d774cde2373775 \
--hash=sha256:571e87c3401fa2bce6eaa0e0749d84f852fc18a0f22aceb72ee66bcfba8c6391
django-import-export==2.6.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:056624f3d6af04f74ed7adc0ba64841a9ff033162432c668877b53a6832e6c57 \
--hash=sha256:c8509fcc5176a34f1c90fc15aeaedcb8011c6a397ef64caf0b38eabcd723a9f9
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:1294f916f3b3475e40e1b0ec1bd320aa2397978eae672721c81cbc2ed517e9ee \
--hash=sha256:116bd0d7940f09bf7ffd465943992e23d87e772a9d6c0d3a57b74040589a383b
django-import-export==2.7.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4bc65943a5ce66aeaf2b5d0d6f75b1863b63b10323bf235e46500bef5d6dd85b \
--hash=sha256:254ca359782efca932c398edabc15dd51d31da241e85cc03af5b720173e0b2fe
django-ipware==4.0.2; 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:602a58325a4808bd19197fef2676a0b2da2df40d0ecf21be414b2ff48c72ad05 \
--hash=sha256:878dbb06a87e25550798e9ef3204ed70a200dd8b15e47dcef848cf08244f04c9
django-processinfo==1.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:3cacad233a5428a5cc6292eafbfddd97948d8d1e4f47e47175a7fcdfcee90f12 \
--hash=sha256:08aefdf7285d1eaa595e46570bcc12f2dfd9e24594d524246110614819076b6c
django-redis==5.0.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:048f665bbe27f8ff2edebae6aa9c534ab137f1e8fa7234147ef470df3f3aa9b8 \
--hash=sha256:97739ca9de3f964c51412d1d7d8aecdfd86737bb197fce6e1ff12620c63c97ee
django-redis==5.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de \
--hash=sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026
django-tools==0.49.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:9da6d5610576a34219be3dea9c7c2207669e5c916d89987011843ded772ece0a \
--hash=sha256:a27c32cff98cd82dde23ab2f05fb9e06a32aaeb8357e96f1ec02a634b6619170
django-yunohost-integration==0.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:e5290ea079bf0f340c73445b9655957fafa1dd4042ae8dcf3ace2f903fceda05 \
--hash=sha256:5f6c02a9bffb90449a2bcefc8f75736da8731c4aea6c033b5c35ff8906b79424
django==2.2.24; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \
--hash=sha256:f2084ceecff86b1e631c2cd4107d435daf4e12f1efcdf11061a73bf0b5e95f92 \
--hash=sha256:3339ff0e03dee13045aef6ae7b523edff75b6d726adf7a7a48f53d5a501f7db7
django-yunohost-integration==0.2.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:f5cdb5480025e90de0221d2b1c6282f517fd0c903702563cccb771cb3e1d9417 \
--hash=sha256:a4b3617a3b39225d6162fa88827e9fe8b65388e26a0bbc23ea665c62aa8cb044
django==2.2.28; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \
--hash=sha256:365429d07c1336eb42ba15aa79f45e1c13a0b04d5c21569e7d596696418a6a45 \
--hash=sha256:0200b657afbf1bc08003845ddda053c7641b9b24951e52acd51f6abda33a7413
et-xmlfile==1.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada \
--hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c
fonttools==4.28.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:eff1da7ea274c54cb8842853005a139f711646cbf6f1bcfb6c9b86a627f35ff0 \
--hash=sha256:dca694331af74c8ad47acc5171e57f6b78fac5692bf050f2ab572964577ac0dd
fonttools==4.32.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:b038d1a0dee0079de7ade57071e2e2aced6e35bd697de244ac62938b2b1628c1 \
--hash=sha256:59a90de72149893167e3d552ae2402c6874e006b9adc3feaf5f6d706fe20d392
geographiclib==1.52; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:8f441c527b0b8a26cd96c965565ff0513d1e4d9952b704bf449409e5015c77b7 \
--hash=sha256:ac400d672b8954b0306bca890b088bb8ba2a757dc8133cca0b878f34b33b2740
@ -83,159 +86,160 @@ geopy==2.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \
gpxpy==1.5.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:e6993a8945eae07a833cd304b88bbc6c3c132d63b2bf4a9b0a5d9097616b8708
gunicorn==20.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \
--hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8
icdiff==2.0.4; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:c72572e5ce087bc7a7748af2664764d4a805897caeefb665bdc12677fefb2212
icdiff==2.0.5; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:35d24b728e48b7e0a12bdb69386d3bfc7eef4fe922d0ac1cd70d6e5c11630bae
idna==3.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.6.0" \
--hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
--hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
importlib-metadata==4.2.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b \
--hash=sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31
kiwisolver==1.3.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6 \
--hash=sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470 \
--hash=sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298 \
--hash=sha256:2210f28778c7d2ee13f3c2a20a3a22db889e75f4ec13a21072eabb5693801e84 \
--hash=sha256:82f49c5a79d3839bc8f38cb5f4bfc87e15f04cbafa5fbd12fb32c941cb529cfb \
--hash=sha256:9661a04ca3c950a8ac8c47f53cbc0b530bce1b52f516a1e87b7736fec24bfff0 \
--hash=sha256:2ddb500a2808c100e72c075cbb00bf32e62763c82b6a882d403f01a119e3f402 \
--hash=sha256:72be6ebb4e92520b9726d7146bc9c9b277513a57a38efcf66db0620aec0097e0 \
--hash=sha256:83d2c9db5dfc537d0171e32de160461230eb14663299b7e6d18ca6dca21e4977 \
--hash=sha256:cba430db673c29376135e695c6e2501c44c256a81495da849e85d1793ee975ad \
--hash=sha256:4116ba9a58109ed5e4cb315bdcbff9838f3159d099ba5259c7c7fb77f8537492 \
--hash=sha256:19554bd8d54cf41139f376753af1a644b63c9ca93f8f72009d50a2080f870f77 \
--hash=sha256:a7a4cf5bbdc861987a7745aed7a536c6405256853c94abc9f3287c3fa401b174 \
--hash=sha256:0007840186bacfaa0aba4466d5890334ea5938e0bb7e28078a0eb0e63b5b59d5 \
--hash=sha256:ec2eba188c1906b05b9b49ae55aae4efd8150c61ba450e6721f64620c50b59eb \
--hash=sha256:3dbb3cea20b4af4f49f84cffaf45dd5f88e8594d18568e0225e6ad9dec0e7967 \
--hash=sha256:5326ddfacbe51abf9469fe668944bc2e399181a2158cb5d45e1d40856b2a0589 \
--hash=sha256:c6572c2dab23c86a14e82c245473d45b4c515314f1f859e92608dcafbd2f19b8 \
--hash=sha256:b5074fb09429f2b7bc82b6fb4be8645dcbac14e592128beeff5461dcde0af09f \
--hash=sha256:22521219ca739654a296eea6d4367703558fba16f98688bd8ce65abff36eaa84 \
--hash=sha256:c358721aebd40c243894298f685a19eb0491a5c3e0b923b9f887ef1193ddf829 \
--hash=sha256:7ba5a1041480c6e0a8b11a9544d53562abc2d19220bfa14133e0cdd9967e97af \
--hash=sha256:44e6adf67577dbdfa2d9f06db9fbc5639afefdb5bf2b4dfec25c3a7fbc619536 \
--hash=sha256:1d45d1c74f88b9f41062716c727f78f2a59a5476ecbe74956fafb423c5c87a76 \
--hash=sha256:70adc3658138bc77a36ce769f5f183169bc0a2906a4f61f09673f7181255ac9b \
--hash=sha256:b6a5431940f28b6de123de42f0eb47b84a073ee3c3345dc109ad550a3307dd28 \
--hash=sha256:ee040a7de8d295dbd261ef2d6d3192f13e2b08ec4a954de34a6fb8ff6422e24c \
--hash=sha256:8dc3d842fa41a33fe83d9f5c66c0cc1f28756530cd89944b63b072281e852031 \
--hash=sha256:a498bcd005e8a3fedd0022bb30ee0ad92728154a8798b703f394484452550507 \
--hash=sha256:80efd202108c3a4150e042b269f7c78643420cc232a0a771743bb96b742f838f \
--hash=sha256:f8eb7b6716f5b50e9c06207a14172cf2de201e41912ebe732846c02c830455b9 \
--hash=sha256:f441422bb313ab25de7b3dbfd388e790eceb76ce01a18199ec4944b369017009 \
--hash=sha256:30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6 \
--hash=sha256:2f8f6c8f4f1cff93ca5058d6ec5f0efda922ecb3f4c5fb76181f327decff98b8 \
--hash=sha256:ba677bcaff9429fd1bf01648ad0901cea56c0d068df383d5f5856d88221fe75b \
--hash=sha256:7843b1624d6ccca403a610d1277f7c28ad184c5aa88a1750c1a999754e65b439 \
--hash=sha256:e6f5eb2f53fac7d408a45fbcdeda7224b1cfff64919d0f95473420a931347ae9 \
--hash=sha256:eedd3b59190885d1ebdf6c5e0ca56828beb1949b4dfe6e5d0256a461429ac386 \
--hash=sha256:dedc71c8eb9c5096037766390172c34fb86ef048b8e8958b4e484b9e505d66bc \
--hash=sha256:bf7eb45d14fc036514c09554bf983f2a72323254912ed0c3c8e697b62c4c158f \
--hash=sha256:2b65bd35f3e06a47b5c30ea99e0c2b88f72c6476eedaf8cfbc8e66adb5479dcf \
--hash=sha256:25405f88a37c5f5bcba01c6e350086d65e7465fd1caaf986333d2a045045a223 \
--hash=sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560 \
--hash=sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c
lxml==4.6.4; 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:bbf2dc330bd44bfc0254ab37677ec60f7c7ecea55ad8ba1b8b2ea7bf20c265f5 \
--hash=sha256:b667c51682fe9b9788c69465956baa8b6999531876ccedcafc895c74ad716cd8 \
--hash=sha256:72e730d33fe2e302fd07285f14624fca5e5e2fb2bb4fb2c3941e318c41c443d1 \
--hash=sha256:433df8c7dde0f9e41cbf4f36b0829d50a378116ef5e962ba3881f2f5f025c7be \
--hash=sha256:35752ee40f7bbf6adc9ff4e1f4b84794a3593736dcce80db32e3c2aa85e294ac \
--hash=sha256:5ff5bb2a198ea67403bb6818705e9a4f90e0313f2215428ec51001ce56d939fb \
--hash=sha256:9b87727561c1150c0cc91c5d9d389448b37a7d15f0ba939ed3d1acb2f11bf6c5 \
--hash=sha256:45fdb2899c755138722797161547a40b3e2a06feda620cc41195ee7e97806d81 \
--hash=sha256:38b9de0de3aa689fe9fb9877ae1be1e83b8cf9621f7e62049d0436b9ecf4ad64 \
--hash=sha256:662523cd2a0246740225c7e32531f2e766544122e58bee70e700a024cfc0cf81 \
--hash=sha256:4aa349c5567651f34d4eaae7de6ed5b523f6d70a288f9c6fbac22d13a0784e04 \
--hash=sha256:08eb9200d88b376a8ed5e50f1dc1d1a45b49305169674002a3b5929943390591 \
--hash=sha256:bdc224f216ead849e902151112efef6e96c41ee1322e15d4e5f7c8a826929aee \
--hash=sha256:ab6db93a2b6b66cbf62b4e4a7135f476e708e8c5c990d186584142c77d7f975a \
--hash=sha256:50790313df028aa05cf22be9a8da033b86c42fa32523e4fd944827b482b17bf0 \
--hash=sha256:6764998345552b1dfc9326a932d2bad6367c6b37a176bb73ada6b9486bf602f7 \
--hash=sha256:543b239b191bb3b6d9bef5f09f1fb2be5b7eb09ab4d386aa655e4d53fbe9ff47 \
--hash=sha256:a75c1ad05eedb1a3ff2a34a52a4f0836cfaa892e12796ba39a7732c82701eff4 \
--hash=sha256:47e955112ce64241fdb357acf0216081f9f3255b3ac9c502ca4b3323ec1ca558 \
--hash=sha256:20d7c8d90d449c6a353b15ee0459abae8395dbe59ad01e406ccbf30cd81c6f98 \
--hash=sha256:240db6f3228d26e3c6f4fad914b9ddaaf8707254e8b3efd564dc680c8ec3c264 \
--hash=sha256:351482da8dd028834028537f08724b1de22d40dcf3bb723b469446564f409074 \
--hash=sha256:e678a643177c0e5ec947b645fa7bc84260dfb9b6bf8fb1fdd83008dfc2ca5928 \
--hash=sha256:15d0381feb56f08f78c5cc4fc385ddfe0bde1456e37f54a9322833371aec4060 \
--hash=sha256:4ba74afe5ee5cb5e28d83b513a6e8f0875fda1dc1a9aea42cc0065f029160d2a \
--hash=sha256:9c91a73971a922c13070fd8fa5a114c858251791ba2122a941e6aa781c713e44 \
--hash=sha256:6020c70ff695106bf80651953a23e37718ef1fee9abd060dcad8e32ab2dc13f3 \
--hash=sha256:f5dd358536b8a964bf6bd48de038754c1609e72e5f17f5d21efe2dda17594dbf \
--hash=sha256:7ae7089d81fc502df4b217ad77f03c54039fe90dac0acbe70448d7e53bfbc57e \
--hash=sha256:80d10d53d3184837445ff8562021bdd37f57c4cadacbf9d8726cc16220a00d54 \
--hash=sha256:e95da348d57eb448d226a44b868ff2ca5786fbcbe417ac99ff62d0a7d724b9c7 \
--hash=sha256:ffd65cfa33fed01735c82aca640fde4cc63f0414775cba11e06f84fae2085a6e \
--hash=sha256:877666418598f6cb289546c77ff87590cfd212f903b522b0afa0b9fb73b3ccfb \
--hash=sha256:e91d24623e747eeb2d8121f4a94c6a7ad27dc48e747e2dc95bfe88632bd028a2 \
--hash=sha256:4ec9a80dd5704ecfde54319b6964368daf02848c8954d3bacb9b64d1c7659159 \
--hash=sha256:2901625f4a878a055d275beedc20ba9cb359cefc4386a967222fee29eb236038 \
--hash=sha256:b567178a74a2261345890eac66fbf394692a6e002709d329f28a673ca6042473 \
--hash=sha256:4717123f7c11c81e0da69989e5a64079c3f402b0efeb4c6241db6c369d657bd8 \
--hash=sha256:cf201bf5594d1aab139fe53e3fca457e4f8204a5bbd65d48ab3b82a16f517868 \
--hash=sha256:a77a3470ba37e11872c75ca95baf9b3312133a3d5a5dc720803b23098c653976 \
--hash=sha256:619c6d2b552bba00491e96c0518aad94002651c108a0f7364ff2d7798812c00e \
--hash=sha256:601f0ab75538b280aaf1e720eb9d68d4fa104ac274e1e9e6971df488f4dcdb0f \
--hash=sha256:75d3c5bbc0ddbad03bb68b9be638599f67e4b98ed3dcd0fec9f6f39e41ee96cb \
--hash=sha256:4341d135f5660db10184963d9c3418c3e28d7f868aaf8b11a323ebf85813f7f4 \
--hash=sha256:9db24803fa71e3305fe4a7812782b708da21a0b774b130dd1860cf40a6d7a3ee \
--hash=sha256:afd60230ad9d8bcba005945ec3a343722f09e0b7f8ae804246e5d2cfc6bd71a6 \
--hash=sha256:0c15e1cd55055956e77b0732270f1c6005850696bc3ef3e03d01e78af84eaa42 \
--hash=sha256:6d422b3c729737d8a39279a25fa156c983a56458f8b2f97661ee6fb22b80b1d6 \
--hash=sha256:2eb90f6ec3c236ef2f1bb38aee7c0d23e77d423d395af6326e7cca637519a4cb \
--hash=sha256:51a0e5d243687596f46e24e464121d4b232ad772e2d1785b2a2c0eb413c285d4 \
--hash=sha256:d43bd68714049c84e297c005456a15ecdec818f7b5aa5868c8b0a865cfb78a44 \
--hash=sha256:ee9e4b07b0eba4b6a521509e9e1877476729c1243246b6959de697ebea739643 \
--hash=sha256:48eaac2991b3036175b42ee8d3c23f4cca13f2be8426bf29401a690ab58c88f4 \
--hash=sha256:2b06a91cf7b8acea7793006e4ae50646cef0fe35ce5acd4f5cb1c77eb228e4a1 \
--hash=sha256:523f195948a1ba4f9f5b7294d83c6cd876547dc741820750a7e5e893a24bbe38 \
--hash=sha256:b0ca0ada9d3bc18bd6f611bd001a28abdd49ab9698bd6d717f7f5394c8e94628 \
--hash=sha256:197b7cb7a753cf553a45115739afd8458464a28913da00f5c525063f94cd3f48 \
--hash=sha256:6298f5b42a26581206ef63fffa97c754245d329414108707c525512a5197f2ba \
--hash=sha256:0b12c95542f04d10cba46b3ff28ea52ea56995b78cf918f0b11b05e75812bb79 \
--hash=sha256:daf9bd1fee31f1c7a5928b3e1059e09a8d683ea58fb3ffc773b6c88cb8d1399c
kiwisolver==1.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:6e395ece147f0692ca7cdb05a028d31b83b72c369f7b4a2c1798f4b96af1e3d8 \
--hash=sha256:0b7f50a1a25361da3440f07c58cd1d79957c2244209e4f166990e770256b6b0b \
--hash=sha256:3c032c41ae4c3a321b43a3650e6ecc7406b99ff3e5279f24c9b310f41bc98479 \
--hash=sha256:1dcade8f6fe12a2bb4efe2cbe22116556e3b6899728d3b2a0d3b367db323eacc \
--hash=sha256:0e45e780a74416ef2f173189ef4387e44b5494f45e290bcb1f03735faa6779bf \
--hash=sha256:9d2bb56309fb75a811d81ed55fbe2208aa77a3a09ff5f546ca95e7bb5fac6eff \
--hash=sha256:69b2d6c12f2ad5f55104a36a356192cfb680c049fe5e7c1f6620fc37f119cdc2 \
--hash=sha256:262c248c60f22c2b547683ad521e8a3db5909c71f679b93876921549107a0c24 \
--hash=sha256:1008346a7741620ab9cc6c96e8ad9b46f7a74ce839dbb8805ddf6b119d5fc6c2 \
--hash=sha256:6ece2e12e4b57bc5646b354f436416cd2a6f090c1dadcd92b0ca4542190d7190 \
--hash=sha256:b978afdb913ca953cf128d57181da2e8798e8b6153be866ae2a9c446c6162f40 \
--hash=sha256:7f88c4b8e449908eeddb3bbd4242bd4dc2c7a15a7aa44bb33df893203f02dc2d \
--hash=sha256:e348f1904a4fab4153407f7ccc27e43b2a139752e8acf12e6640ba683093dd96 \
--hash=sha256:c839bf28e45d7ddad4ae8f986928dbf5a6d42ff79760d54ec8ada8fb263e097c \
--hash=sha256:8ae5a071185f1a93777c79a9a1e67ac46544d4607f18d07131eece08d415083a \
--hash=sha256:c222f91a45da9e01a9bc4f760727ae49050f8e8345c4ff6525495f7a164c8973 \
--hash=sha256:a4e8f072db1d6fb7a7cc05a6dbef8442c93001f4bb604f1081d8c2db3ca97159 \
--hash=sha256:be9a650890fb60393e60aacb65878c4a38bb334720aa5ecb1c13d0dac54dd73b \
--hash=sha256:8ec2e55bf31b43aabe32089125dca3b46fdfe9f50afbf0756ae11e14c97b80ca \
--hash=sha256:1d1078ba770d6165abed3d9a1be1f9e79b61515de1dd00d942fa53bba79f01ae \
--hash=sha256:cbb5eb4a2ea1ffec26268d49766cafa8f957fe5c1b41ad00733763fae77f9436 \
--hash=sha256:2e6cda72db409eefad6b021e8a4f964965a629f577812afc7860c69df7bdb84a \
--hash=sha256:b1605c7c38cc6a85212dfd6a641f3905a33412e49f7c003f35f9ac6d71f67720 \
--hash=sha256:81237957b15469ea9151ec8ca08ce05656090ffabc476a752ef5ad7e2644c526 \
--hash=sha256:240009fdf4fa87844f805e23f48995537a8cb8f8c361e35fda6b5ac97fcb906f \
--hash=sha256:240c2d51d098395c012ddbcb9bd7b3ba5de412a1d11840698859f51d0e643c4f \
--hash=sha256:8b6086aa6936865962b2cee0e7aaecf01ab6778ce099288354a7229b4d9f1408 \
--hash=sha256:0d98dca86f77b851350c250f0149aa5852b36572514d20feeadd3c6b1efe38d0 \
--hash=sha256:91eb4916271655dfe3a952249cb37a5c00b6ba68b4417ee15af9ba549b5ba61d \
--hash=sha256:fa4d97d7d2b2c082e67907c0b8d9f31b85aa5d3ba0d33096b7116f03f8061261 \
--hash=sha256:71469b5845b9876b8d3d252e201bef6f47bf7456804d2fbe9a1d6e19e78a1e65 \
--hash=sha256:8ff3033e43e7ca1389ee59fb7ecb8303abb8713c008a1da49b00869e92e3dd7c \
--hash=sha256:89b57c2984f4464840e4b768affeff6b6809c6150d1166938ade3e22fbe22db8 \
--hash=sha256:ffbdb9a96c536f0405895b5e21ee39ec579cb0ed97bdbd169ae2b55f41d73219 \
--hash=sha256:8a830a03970c462d1a2311c90e05679da56d3bd8e78a4ba9985cb78ef7836c9f \
--hash=sha256:f74f2a13af201559e3d32b9ddfc303c94ae63d63d7f4326d06ce6fe67e7a8255 \
--hash=sha256:e677cc3626287f343de751e11b1e8a5b915a6ac897e8aecdbc996cd34de753a0 \
--hash=sha256:b3e251e5c38ac623c5d786adb21477f018712f8c6fa54781bd38aa1c60b60fc2 \
--hash=sha256:0c380bb5ae20d829c1a5473cfcae64267b73aaa4060adc091f6df1743784aae0 \
--hash=sha256:484f2a5f0307bc944bc79db235f41048bae4106ffa764168a068d88b644b305d \
--hash=sha256:0e8afdf533b613122e4bbaf3c1e42c2a5e9e2d1dd3a0a017749a7658757cb377 \
--hash=sha256:42f6ef9b640deb6f7d438e0a371aedd8bef6ddfde30683491b2e6f568b4e884e \
--hash=sha256:7f606d91b8a8816be476513a77fd30abe66227039bd6f8b406c348cb0247dcc9
lxml==4.8.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" \
--hash=sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b \
--hash=sha256:28d1af847786f68bec57961f31221125c29d6f52d9187c01cd34dc14e2b29430 \
--hash=sha256:b92d40121dcbd74831b690a75533da703750f7041b4bf951befc657c37e5695a \
--hash=sha256:e01f9531ba5420838c801c21c1b0f45dbc9607cb22ea2cf132844453bec863a5 \
--hash=sha256:6259b511b0f2527e6d55ad87acc1c07b3cbffc3d5e050d7e7bcfa151b8202df9 \
--hash=sha256:1010042bfcac2b2dc6098260a2ed022968dbdfaf285fc65a3acf8e4eb1ffd1bc \
--hash=sha256:fa56bb08b3dd8eac3a8c5b7d075c94e74f755fd9d8a04543ae8d37b1612dd170 \
--hash=sha256:31ba2cbc64516dcdd6c24418daa7abff989ddf3ba6d3ea6f6ce6f2ed6e754ec9 \
--hash=sha256:31499847fc5f73ee17dbe1b8e24c6dafc4e8d5b48803d17d22988976b0171f03 \
--hash=sha256:5f7d7d9afc7b293147e2d506a4596641d60181a35279ef3aa5778d0d9d9123fe \
--hash=sha256:a3c5f1a719aa11866ffc530d54ad965063a8cbbecae6515acbd5f0fae8f48eaa \
--hash=sha256:6268e27873a3d191849204d00d03f65c0e343b3bcb518a6eaae05677c95621d1 \
--hash=sha256:330bff92c26d4aee79c5bc4d9967858bdbe73fdbdbacb5daf623a03a914fe05b \
--hash=sha256:b2582b238e1658c4061ebe1b4df53c435190d22457642377fd0cb30685cdfb76 \
--hash=sha256:a2bfc7e2a0601b475477c954bf167dee6d0f55cb167e3f3e7cefad906e7759f6 \
--hash=sha256:a1547ff4b8a833511eeaceacbcd17b043214fcdb385148f9c1bc5556ca9623e2 \
--hash=sha256:a9f1c3489736ff8e1c7652e9dc39f80cff820f23624f23d9eab6e122ac99b150 \
--hash=sha256:530f278849031b0eb12f46cca0e5db01cfe5177ab13bd6878c6e739319bae654 \
--hash=sha256:078306d19a33920004addeb5f4630781aaeabb6a8d01398045fcde085091a169 \
--hash=sha256:86545e351e879d0b72b620db6a3b96346921fa87b3d366d6c074e5a9a0b8dadb \
--hash=sha256:24f5c5ae618395ed871b3d8ebfcbb36e3f1091fd847bf54c4de623f9107942f3 \
--hash=sha256:bbab6faf6568484707acc052f4dfc3802bdb0cafe079383fbaa23f1cdae9ecd4 \
--hash=sha256:7993232bd4044392c47779a3c7e8889fea6883be46281d45a81451acfd704d7e \
--hash=sha256:6d6483b1229470e1d8835e52e0ff3c6973b9b97b24cd1c116dca90b57a2cc613 \
--hash=sha256:ad4332a532e2d5acb231a2e5d33f943750091ee435daffca3fec0a53224e7e33 \
--hash=sha256:db3535733f59e5605a88a706824dfcb9bd06725e709ecb017e165fc1d6e7d429 \
--hash=sha256:5f148b0c6133fb928503cfcdfdba395010f997aa44bcf6474fcdd0c5398d9b63 \
--hash=sha256:8a31f24e2a0b6317f33aafbb2f0895c0bce772980ae60c2c640d82caac49628a \
--hash=sha256:719544565c2937c21a6f76d520e6e52b726d132815adb3447ccffbe9f44203c4 \
--hash=sha256:c0b88ed1ae66777a798dc54f627e32d3b81c8009967c63993c450ee4cbcbec15 \
--hash=sha256:fa9b7c450be85bfc6cd39f6df8c5b8cbd76b5d6fc1f69efec80203f9894b885f \
--hash=sha256:e9f84ed9f4d50b74fbc77298ee5c870f67cb7e91dcdc1a6915cb1ff6a317476c \
--hash=sha256:1d650812b52d98679ed6c6b3b55cbb8fe5a5460a0aef29aeb08dc0b44577df85 \
--hash=sha256:80bbaddf2baab7e6de4bc47405e34948e694a9efe0861c61cdc23aa774fcb141 \
--hash=sha256:6f7b82934c08e28a2d537d870293236b1000d94d0b4583825ab9649aef7ddf63 \
--hash=sha256:e1fd7d2fe11f1cb63d3336d147c852f6d07de0d0020d704c6031b46a30b02ca8 \
--hash=sha256:5045ee1ccd45a89c4daec1160217d363fcd23811e26734688007c26f28c9e9e7 \
--hash=sha256:0c1978ff1fd81ed9dcbba4f91cf09faf1f8082c9d72eb122e92294716c605428 \
--hash=sha256:52cbf2ff155b19dc4d4100f7442f6a697938bf4493f8d3b0c51d45568d5666b5 \
--hash=sha256:ce13d6291a5f47c1c8dbd375baa78551053bc6b5e5c0e9bb8e39c0a8359fd52f \
--hash=sha256:e11527dc23d5ef44d76fef11213215c34f36af1608074561fcc561d983aeb870 \
--hash=sha256:60d2f60bd5a2a979df28ab309352cdcf8181bda0cca4529769a945f09aba06f9 \
--hash=sha256:62f93eac69ec0f4be98d1b96f4d6b964855b8255c345c17ff12c20b93f247b68 \
--hash=sha256:20b8a746a026017acf07da39fdb10aa80ad9877046c9182442bf80c84a1c4696 \
--hash=sha256:891dc8f522d7059ff0024cd3ae79fd224752676447f9c678f2a5c14b84d9a939 \
--hash=sha256:b6fc2e2fb6f532cf48b5fed57567ef286addcef38c28874458a41b7837a57807 \
--hash=sha256:74eb65ec61e3c7c019d7169387d1b6ffcfea1b9ec5894d116a9a903636e4a0b1 \
--hash=sha256:627e79894770783c129cc5e89b947e52aa26e8e0557c7e205368a809da4b7939 \
--hash=sha256:545bd39c9481f2e3f2727c78c169425efbfb3fbba6e7db4f46a80ebb249819ca \
--hash=sha256:5a58d0b12f5053e270510bf12f753a76aaf3d74c453c00942ed7d2c804ca845c \
--hash=sha256:ec4b4e75fc68da9dc0ed73dcdb431c25c57775383fec325d23a770a64e7ebc87 \
--hash=sha256:5804e04feb4e61babf3911c2a974a5b86f66ee227cc5006230b00ac6d285b3a9 \
--hash=sha256:aa0cf4922da7a3c905d000b35065df6184c0dc1d866dd3b86fd961905bbad2ea \
--hash=sha256:dd10383f1d6b7edf247d0960a3db274c07e96cf3a3fc7c41c8448f93eac3fb1c \
--hash=sha256:2403a6d6fb61c285969b71f4a3527873fe93fd0abe0832d858a17fe68c8fa507 \
--hash=sha256:986b7a96228c9b4942ec420eff37556c5777bfba6758edcb95421e4a614b57f9 \
--hash=sha256:6fe4ef4402df0250b75ba876c3795510d782def5c1e63890bde02d622570d39e \
--hash=sha256:f10ce66fcdeb3543df51d423ede7e238be98412232fca5daec3e54bcd16b8da0 \
--hash=sha256:730766072fd5dcb219dd2b95c4c49752a54f00157f322bc6d71f7d2a31fecd79 \
--hash=sha256:8b99ec73073b37f9ebe8caf399001848fced9c08064effdbfc4da2b5a8d07b93 \
--hash=sha256:f63f62fc60e6228a4ca9abae28228f35e1bd3ce675013d1dfb828688d50c6e23
markuppy==1.14; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f
matplotlib==3.5.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4b018ea6f26424a0852eb60eb406420d9f0d34f65736ea7bbfbb104946a66d86 \
--hash=sha256:a07ff2565da72a7b384a9e000b15b6b8270d81370af8a3531a16f6fbcee023cc \
--hash=sha256:2eea16883aa7724c95eea0eb473ab585c6cf66f0e28f7f13e63deb38f4fd6d0f \
--hash=sha256:0e020a42f3338823a393dd2f80e39a2c07b9f941dfe2c778eb104eeb33d60bb5 \
--hash=sha256:9bac8eb1eccef540d7f4e844b6313d9f7722efd48c07e1b4bfec1056132127fd \
--hash=sha256:7a7cb59ebd63a8ac4542ec1c61dd08724f82ec3aa7bb6b4b9e212d43c611ce3d \
--hash=sha256:6e0e6b2111165522ad336705499b1f968c34a9e84d05d498ee5af0b5697d1efe \
--hash=sha256:ff5d9fe518ad2de14ce82ab906b6ab5c2b0c7f4f984400ff8a7a905daa580a0a \
--hash=sha256:66b172610db0ececebebb09d146f54205f87c7b841454e408fba854764f91bdd \
--hash=sha256:ee3d9ff16d749a9aa521bd7d86f0dbf256b2d2ac8ce31b19e4d2c86d2f2ff0b6 \
--hash=sha256:970aa97297537540369d05fe0fd1bb952593f9ab696c9b427c06990a83e2418b \
--hash=sha256:153a0cf6a6ff4f406a0600d2034710c49988bacc6313d193b32716f98a697580 \
--hash=sha256:6db02c5605f063b67780f4d5753476b6a4944343284aa4e93c5e8ff6e9ec7f76 \
--hash=sha256:df0042cab69f4d246f4cb8fc297770ac4ae6ec2983f61836b04a117722037dcd \
--hash=sha256:a7bf8b05c214d32fb7ca7c001fde70b9b426378e897b0adbf77b85ea3569d56a \
--hash=sha256:0abf8b51cc6d3ba34d1b15b26e329f23879848a0cf1216954c1f432ffc7e1af7 \
--hash=sha256:13930a0c9bec0fd25f43c448b047a21af1353328b946f044a8fc3be077c6b1a8 \
--hash=sha256:18f6e52386300db5cc4d1e9019ad9da2e80658bab018834d963ebb0aa5355095 \
--hash=sha256:ba107add08e12600b072cf3c47aaa1ab85dd4d3c48107a5d3377d1bf80f8b235 \
--hash=sha256:2089b9014792dcc87bb1d620cde847913338abf7d957ef05587382b0cb76d44e \
--hash=sha256:f23fbf70d2e80f4e03a83fc1206a8306d9bc50482fee4239f10676ce7e470c83 \
--hash=sha256:71a1851111f23f82fc43d2b6b2bfdd3f760579a664ebc939576fe21cc6133d01 \
--hash=sha256:d092b7ba63182d2dd427904e3eb58dd5c46ec67c5968de14a4b5007010a3a4cc \
--hash=sha256:ac17a7e7b06ee426a4989f0b7f24ab1a592e39cdf56353a90f4e998bc0bf44d6 \
--hash=sha256:a5b62d1805cc83d755972033c05cea78a1e177a159fc84da5c9c4ab6303ccbd9 \
--hash=sha256:666d717a4798eb9c5d3ae83fe80c7bc6ed696b93e879cb01cb24a74155c73612 \
--hash=sha256:65f877882b7ddede7090c7d87be27a0f4720fe7fc6fddd4409c06e1aa0f1ae8d \
--hash=sha256:7baf23adb698d8c6ca7339c9dde00931bc47b2dd82fa912827fef9f93db77f5e \
--hash=sha256:b3b687e905da32e5f2e5f16efa713f5d1fcd9fb8b8c697895de35c91fedeb086 \
--hash=sha256:a6cef5b31e27c31253c0f852b629a38d550ae66ec6850129c49d872f9ee428cb \
--hash=sha256:a0dcaf5648cecddc328e81a0421821a1f65a1d517b20746c94a1f0f5c36fb51a \
--hash=sha256:b5e439d9e55d645f2a4dca63e2f66d68fe974c405053b132d61c7e98c25dfeb2 \
--hash=sha256:dc8c5c23e7056e126275dbf29efba817b3d94196690930d0968873ac3a94ab82 \
--hash=sha256:a0ea10faa3bab0714d3a19c7e0921279a68d57552414d6eceaea99f97d7735db \
--hash=sha256:38892a254420d95594285077276162a5e9e9c30b6da08bdc2a4d53331ad9a6fa
matplotlib==3.5.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b \
--hash=sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6 \
--hash=sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4 \
--hash=sha256:53273c5487d1c19c3bc03b9eb82adaf8456f243b97ed79d09dded747abaf1235 \
--hash=sha256:e3b6f3fd0d8ca37861c31e9a7cab71a0ef14c639b4c95654ea1dd153158bf0df \
--hash=sha256:e8c87cdaf06fd7b2477f68909838ff4176f105064a72ca9d24d3f2a29f73d393 \
--hash=sha256:e2f28a07b4f82abb40267864ad7b3a4ed76f1b1663e81c7efc84a9b9248f672f \
--hash=sha256:d70a32ee1f8b55eed3fd4e892f0286df8cccc7e0475c11d33b5d0a148f5c7599 \
--hash=sha256:68fa30cec89b6139dc559ed6ef226c53fd80396da1919a1b5ef672c911aaa767 \
--hash=sha256:2e3484d8455af3fdb0424eae1789af61f6a79da0c80079125112fd5c1b604218 \
--hash=sha256:e293b16cf303fe82995e41700d172a58a15efc5331125d08246b520843ef21ee \
--hash=sha256:e3520a274a0e054e919f5b3279ee5dbccf5311833819ccf3399dab7c83e90a25 \
--hash=sha256:2252bfac85cec7af4a67e494bfccf9080bcba8a0299701eab075f48847cca907 \
--hash=sha256:abf67e05a1b7f86583f6ebd01f69b693b9c535276f4e943292e444855870a1b8 \
--hash=sha256:6c094e4bfecd2fa7f9adffd03d8abceed7157c928c2976899de282f3600f0a3d \
--hash=sha256:506b210cc6e66a0d1c2bb765d055f4f6bc2745070fb1129203b67e85bbfa5c18 \
--hash=sha256:b04fc29bcef04d4e2d626af28d9d892be6aba94856cb46ed52bcb219ceac8943 \
--hash=sha256:577ed20ec9a18d6bdedb4616f5e9e957b4c08563a9f985563a31fd5b10564d2a \
--hash=sha256:e486f60db0cd1c8d68464d9484fd2a94011c1ac8593d765d0211f9daba2bd535 \
--hash=sha256:b71f3a7ca935fc759f2aed7cec06cfe10bc3100fadb5dbd9c435b04e557971e1 \
--hash=sha256:d24e5bb8028541ce25e59390122f5e48c8506b7e35587e5135efcb6471b4ac6c \
--hash=sha256:778d398c4866d8e36ee3bf833779c940b5f57192fa0a549b3ad67bc4c822771b \
--hash=sha256:bb1c613908f11bac270bc7494d68b1ef6e7c224b7a4204d5dacf3522a41e2bc3 \
--hash=sha256:edf5e4e1d5fb22c18820e8586fb867455de3b109c309cb4fce3aaed85d9468d1 \
--hash=sha256:40e0d7df05e8efe60397c69b467fc8f87a2affeb4d562fe92b72ff8937a2b511 \
--hash=sha256:7a350ca685d9f594123f652ba796ee37219bf72c8e0fc4b471473d87121d6d34 \
--hash=sha256:3e66497cd990b1a130e21919b004da2f1dc112132c01ac78011a90a0f9229778 \
--hash=sha256:87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7 \
--hash=sha256:b8a4fb2a0c5afbe9604f8a91d7d0f27b1832c3e0b5e365f95a13015822b4cd65 \
--hash=sha256:fe8d40c434a8e2c68d64c6d6a04e77f21791a93ff6afe0dce169597c110d3079 \
--hash=sha256:34a1fc29f8f96e78ec57a5eff5e8d8b53d3298c3be6df61e7aa9efba26929522 \
--hash=sha256:b19a761b948e939a9e20173aaae76070025f0024fc8f7ba08bef22a5c8573afc \
--hash=sha256:6803299cbf4665eca14428d9e886de62e24f4223ac31ab9c5d6d5339a39782c7 \
--hash=sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a \
--hash=sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c
numpy==1.21.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:38e8648f9449a549a7dfe8d8755a5979b45b3538520d1e735637ef28e8c2dc50 \
--hash=sha256:fd7d7409fa643a91d0a05c7554dd68aa9c9bb16e186f6ccfe40d6e003156e33a \
@ -274,48 +278,45 @@ openpyxl==3.0.9; python_version >= "3.7" and python_full_version < "4.0.0" \
packaging==21.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 \
--hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb
pillow==8.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:81f8d5c81e483a9442d72d182e1fb6dcb9723f289a57e8030811bac9ea3fef8d \
--hash=sha256:3f97cfb1e5a392d75dd8b9fd274d205404729923840ca94ca45a0af57e13dbe6 \
--hash=sha256:eb9fc393f3c61f9054e1ed26e6fe912c7321af2f41ff49d3f83d05bacf22cc78 \
--hash=sha256:d82cdb63100ef5eedb8391732375e6d05993b765f72cb34311fab92103314649 \
--hash=sha256:62cc1afda735a8d109007164714e73771b499768b9bb5afcbbee9d0ff374b43f \
--hash=sha256:e3dacecfbeec9a33e932f00c6cd7996e62f53ad46fbe677577394aaa90ee419a \
--hash=sha256:620582db2a85b2df5f8a82ddeb52116560d7e5e6b055095f04ad828d1b0baa39 \
--hash=sha256:1bc723b434fbc4ab50bb68e11e93ce5fb69866ad621e3c2c9bdb0cd70e345f55 \
--hash=sha256:72cbcfd54df6caf85cc35264c77ede902452d6df41166010262374155947460c \
--hash=sha256:70ad9e5c6cb9b8487280a02c0ad8a51581dcbbe8484ce058477692a27c151c0a \
--hash=sha256:25a49dc2e2f74e65efaa32b153527fc5ac98508d502fa46e74fa4fd678ed6645 \
--hash=sha256:93ce9e955cc95959df98505e4608ad98281fff037350d8c2671c9aa86bcf10a9 \
--hash=sha256:2e4440b8f00f504ee4b53fe30f4e381aae30b0568193be305256b1462216feff \
--hash=sha256:8c803ac3c28bbc53763e6825746f05cc407b20e4a69d0122e526a582e3b5e153 \
--hash=sha256:c8a17b5d948f4ceeceb66384727dde11b240736fddeda54ca740b9b8b1556b29 \
--hash=sha256:1394a6ad5abc838c5cd8a92c5a07535648cdf6d09e8e2d6df916dfa9ea86ead8 \
--hash=sha256:792e5c12376594bfcb986ebf3855aa4b7c225754e9a9521298e460e92fb4a488 \
--hash=sha256:d99ec152570e4196772e7a8e4ba5320d2d27bf22fdf11743dd882936ed64305b \
--hash=sha256:7b7017b61bbcdd7f6363aeceb881e23c46583739cb69a3ab39cb384f6ec82e5b \
--hash=sha256:d89363f02658e253dbd171f7c3716a5d340a24ee82d38aab9183f7fdf0cdca49 \
--hash=sha256:0a0956fdc5defc34462bb1c765ee88d933239f9a94bc37d132004775241a7585 \
--hash=sha256:5b7bb9de00197fb4261825c15551adf7605cf14a80badf1761d61e59da347779 \
--hash=sha256:72b9e656e340447f827885b8d7a15fc8c4e68d410dc2297ef6787eec0f0ea409 \
--hash=sha256:a5a4532a12314149d8b4e4ad8ff09dde7427731fcfa5917ff16d0291f13609df \
--hash=sha256:82aafa8d5eb68c8463b6e9baeb4f19043bb31fefc03eb7b216b51e6a9981ae09 \
--hash=sha256:066f3999cb3b070a95c3652712cffa1a748cd02d60ad7b4e485c3748a04d9d76 \
--hash=sha256:5503c86916d27c2e101b7f71c2ae2cddba01a2cf55b8395b0255fd33fa4d1f1a \
--hash=sha256:4acc0985ddf39d1bc969a9220b51d94ed51695d455c228d8ac29fcdb25810e6e \
--hash=sha256:0b052a619a8bfcf26bd8b3f48f45283f9e977890263e4571f2393ed8898d331b \
--hash=sha256:493cb4e415f44cd601fcec11c99836f707bb714ab03f5ed46ac25713baf0ff20 \
--hash=sha256:b8831cb7332eda5dc89b21a7bce7ef6ad305548820595033a4b03cf3091235ed \
--hash=sha256:5e9ac5f66616b87d4da618a20ab0a38324dbe88d8a39b55be8964eb520021e02 \
--hash=sha256:3eb1ce5f65908556c2d8685a8f0a6e989d887ec4057326f6c22b24e8a172c66b \
--hash=sha256:ddc4d832a0f0b4c52fff973a0d44b6c99839a9d016fe4e6a1cb8f3eea96479c2 \
--hash=sha256:9a3e5ddc44c14042f0844b8cf7d2cd455f6cc80fd7f5eefbe657292cf601d9ad \
--hash=sha256:c70e94281588ef053ae8998039610dbd71bc509e4acbc77ab59d7d2937b10698 \
--hash=sha256:3862b7256046fcd950618ed22d1d60b842e3a40a48236a5498746f21189afbbc \
--hash=sha256:a4901622493f88b1a29bd30ec1a2f683782e57c3c16a2dbc7f2595ba01f639df \
--hash=sha256:84c471a734240653a0ec91dec0996696eea227eafe72a33bd06c92697728046b \
--hash=sha256:244cf3b97802c34c41905d22810846802a3329ddcb93ccc432870243211c79fc \
--hash=sha256:b8e2f83c56e141920c39464b852de3719dfbfb6e3c99a2d8da0edf4fb33176ed
pillow==9.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea \
--hash=sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652 \
--hash=sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a \
--hash=sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7 \
--hash=sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e \
--hash=sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3 \
--hash=sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160 \
--hash=sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033 \
--hash=sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c \
--hash=sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165 \
--hash=sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a \
--hash=sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2 \
--hash=sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244 \
--hash=sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef \
--hash=sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512 \
--hash=sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477 \
--hash=sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b \
--hash=sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378 \
--hash=sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e \
--hash=sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5 \
--hash=sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a \
--hash=sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34 \
--hash=sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717 \
--hash=sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581 \
--hash=sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6 \
--hash=sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4 \
--hash=sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331 \
--hash=sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8 \
--hash=sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58 \
--hash=sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595 \
--hash=sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481 \
--hash=sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0 \
--hash=sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a \
--hash=sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7 \
--hash=sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3 \
--hash=sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8 \
--hash=sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458 \
--hash=sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97
pprintpp==0.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
@ -335,18 +336,18 @@ psycopg2==2.8.6; (python_version >= "2.7" and python_full_version < "3.0.0") or
--hash=sha256:2c93d4d16933fea5bbacbe1aaf8fa8c1348740b2e50b3735d1b0bf8154cbf0f3 \
--hash=sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7 \
--hash=sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543
pyparsing==3.0.6; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
--hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
pyparsing==3.0.8; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.8" \
--hash=sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06 \
--hash=sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954
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:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
--hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
python-stdnum==1.17; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:374e2b5e13912ccdbf50b0b23fca2c3e0531174805c32d74e145f37756328340 \
--hash=sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547
pytz==2021.3; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c \
--hash=sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326
pytz==2022.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c \
--hash=sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7
pyyaml==6.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \
--hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \
@ -381,96 +382,110 @@ pyyaml==6.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \
--hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \
--hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2
redis==4.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:c8481cf414474e3497ec7971a1ba9b998c8efad0f0d289a009a5bbef040894f9 \
--hash=sha256:ccf692811f2c1fc7a92b466aa2599e4a6d2d73d5f736a2c70be600657c0da34a
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:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24 \
--hash=sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7
setuptools-scm==6.3.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4c64444b1d49c4063ae60bfe1680f611c8b13833d556fd1d6050c0023162a119 \
--hash=sha256:a49aa8081eeb3514eb9728fa5040f2eaa962d6c6f4ec9c32f6c1fba88f88a0f2
redis==4.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4e95f4ec5f49e636efcf20061a5a9110c20852f607cfca6865c07aaa8a739ee2 \
--hash=sha256:0107dc8e98a4f1d1d4aa00100e044287f77121a1e6d2085545c4b7fa94a7a27f
requests==2.27.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:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d \
--hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61
setuptools-scm==6.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4 \
--hash=sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30
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:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926
sqlparse==0.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d \
--hash=sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae
svgwrite==1.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:4b21652a1d9c543a6bf4f9f2a54146b214519b7540ca60cb99968ad09ef631d0 \
--hash=sha256:e220a4bf189e7e214a55e8a11421d152b5b6fb1dd660c86a8b6b61fe8cc2ac48
tablib==3.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:26141c9cf2d5904a2228d3f5d45f8a46a3f3f2f0fbb4c33b4a1c1ddca9f31348 \
--hash=sha256:d64c9f6712918a3d90ec5d71b44b8bab1083e3609e4844ad2be80eb633e097ed
tomli==1.2.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:f04066f68f5554911363063a30b108d2b5a5b1a010aa8b6132af78489fe3aade \
--hash=sha256:c6ce0015eb38820eaf32b5db832dbc26deb3dd427bd5f6556cf0acac2c214fee
typing-extensions==4.0.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:829704698b22e13ec9eaf959122315eabb370b0884400e9818334d8b677023d9
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
svgwrite==1.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:ca63d76396d1f6f099a2b2d8cf1419e1c1de8deece9a2b7f4da0632067d71d43 \
--hash=sha256:d304a929f197d31647c287c10eee0f64378058e1c83a9df83433a5980864e59f
tablib==3.2.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:870d7e688f738531a14937a055e8bba404fbc388e77d4d500b2c904075d1019c \
--hash=sha256:a57f2770b8c225febec1cb1e65012a69cf30dd28be810e0ff98d024768c7d0f1
tomli==2.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
typing-extensions==4.1.1; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2 \
--hash=sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42
urllib3==1.26.9; 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:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \
--hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e
webencodings==0.5.1; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
wrapt==1.13.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:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a \
--hash=sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489 \
--hash=sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909 \
--hash=sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229 \
--hash=sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af \
--hash=sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de \
--hash=sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb \
--hash=sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80 \
--hash=sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca \
--hash=sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44 \
--hash=sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056 \
--hash=sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785 \
--hash=sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096 \
--hash=sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33 \
--hash=sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f \
--hash=sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e \
--hash=sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d \
--hash=sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179 \
--hash=sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3 \
--hash=sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755 \
--hash=sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851 \
--hash=sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13 \
--hash=sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918 \
--hash=sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade \
--hash=sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc \
--hash=sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf \
--hash=sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125 \
--hash=sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36 \
--hash=sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10 \
--hash=sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068 \
--hash=sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709 \
--hash=sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df \
--hash=sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2 \
--hash=sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b \
--hash=sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829 \
--hash=sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea \
--hash=sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9 \
--hash=sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554 \
--hash=sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c \
--hash=sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b \
--hash=sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce \
--hash=sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79 \
--hash=sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb \
--hash=sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb \
--hash=sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32 \
--hash=sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7 \
--hash=sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e \
--hash=sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640 \
--hash=sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374 \
--hash=sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb \
--hash=sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185
wrapt==1.14.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" \
--hash=sha256:5a9a1889cc01ed2ed5f34574c90745fab1dd06ec2eee663e8ebeefe363e8efd7 \
--hash=sha256:9a3ff5fb015f6feb78340143584d9f8a0b91b6293d6b5cf4295b3e95d179b88c \
--hash=sha256:4b847029e2d5e11fd536c9ac3136ddc3f54bc9488a75ef7d040a3900406a91eb \
--hash=sha256:9a5a544861b21e0e7575b6023adebe7a8c6321127bb1d238eb40d99803a0e8bd \
--hash=sha256:88236b90dda77f0394f878324cfbae05ae6fde8a84d548cfe73a75278d760291 \
--hash=sha256:f0408e2dbad9e82b4c960274214af533f856a199c9274bd4aff55d4634dedc33 \
--hash=sha256:9d8c68c4145041b4eeae96239802cfdfd9ef927754a5be3f50505f09f309d8c6 \
--hash=sha256:22626dca56fd7f55a0733e604f1027277eb0f4f3d95ff28f15d27ac25a45f71b \
--hash=sha256:65bf3eb34721bf18b5a021a1ad7aa05947a1767d1aa272b725728014475ea7d5 \
--hash=sha256:09d16ae7a13cff43660155383a2372b4aa09109c7127aa3f24c3cf99b891c330 \
--hash=sha256:debaf04f813ada978d7d16c7dfa16f3c9c2ec9adf4656efdc4defdf841fc2f0c \
--hash=sha256:748df39ed634851350efa87690c2237a678ed794fe9ede3f0d79f071ee042561 \
--hash=sha256:1807054aa7b61ad8d8103b3b30c9764de2e9d0c0978e9d3fc337e4e74bf25faa \
--hash=sha256:763a73ab377390e2af26042f685a26787c402390f682443727b847e9496e4a2a \
--hash=sha256:8529b07b49b2d89d6917cfa157d3ea1dfb4d319d51e23030664a827fe5fd2131 \
--hash=sha256:68aeefac31c1f73949662ba8affaf9950b9938b712fb9d428fa2a07e40ee57f8 \
--hash=sha256:59d7d92cee84a547d91267f0fea381c363121d70fe90b12cd88241bd9b0e1763 \
--hash=sha256:3a88254881e8a8c4784ecc9cb2249ff757fd94b911d5df9a5984961b96113fff \
--hash=sha256:9a242871b3d8eecc56d350e5e03ea1854de47b17f040446da0e47dc3e0b9ad4d \
--hash=sha256:a65bffd24409454b889af33b6c49d0d9bcd1a219b972fba975ac935f17bdf627 \
--hash=sha256:9d9fcd06c952efa4b6b95f3d788a819b7f33d11bea377be6b8980c95e7d10775 \
--hash=sha256:db6a0ddc1282ceb9032e41853e659c9b638789be38e5b8ad7498caac00231c23 \
--hash=sha256:14e7e2c5f5fca67e9a6d5f753d21f138398cad2b1159913ec9e9a67745f09ba3 \
--hash=sha256:6d9810d4f697d58fd66039ab959e6d37e63ab377008ef1d63904df25956c7db0 \
--hash=sha256:d808a5a5411982a09fef6b49aac62986274ab050e9d3e9817ad65b2791ed1425 \
--hash=sha256:b77159d9862374da213f741af0c361720200ab7ad21b9f12556e0eb95912cd48 \
--hash=sha256:36a76a7527df8583112b24adc01748cd51a2d14e905b337a6fefa8b96fc708fb \
--hash=sha256:a0057b5435a65b933cbf5d859cd4956624df37b8bf0917c71756e4b3d9958b9e \
--hash=sha256:3a0a4ca02752ced5f37498827e49c414d694ad7cf451ee850e3ff160f2bee9d3 \
--hash=sha256:8c6be72eac3c14baa473620e04f74186c5d8f45d80f8f2b4eda6e1d18af808e8 \
--hash=sha256:21b1106bff6ece8cb203ef45b4f5778d7226c941c83aaaa1e1f0f4f32cc148cd \
--hash=sha256:493da1f8b1bb8a623c16552fb4a1e164c0200447eb83d3f68b44315ead3f9036 \
--hash=sha256:89ba3d548ee1e6291a20f3c7380c92f71e358ce8b9e48161401e087e0bc740f8 \
--hash=sha256:729d5e96566f44fccac6c4447ec2332636b4fe273f03da128fff8d5559782b06 \
--hash=sha256:891c353e95bb11abb548ca95c8b98050f3620a7378332eb90d6acdef35b401d4 \
--hash=sha256:23f96134a3aa24cc50614920cc087e22f87439053d886e474638c68c8d15dc80 \
--hash=sha256:6807bcee549a8cb2f38f73f469703a1d8d5d990815c3004f21ddb68a567385ce \
--hash=sha256:6915682f9a9bc4cf2908e83caf5895a685da1fbd20b6d485dafb8e218a338279 \
--hash=sha256:f2f3bc7cd9c9fcd39143f11342eb5963317bd54ecc98e3650ca22704b69d9653 \
--hash=sha256:3a71dbd792cc7a3d772ef8cd08d3048593f13d6f40a11f3427c000cf0a5b36a0 \
--hash=sha256:5a0898a640559dec00f3614ffb11d97a2666ee9a2a6bad1259c9facd01a1d4d9 \
--hash=sha256:167e4793dc987f77fd476862d32fa404d42b71f6a85d3b38cbce711dba5e6b68 \
--hash=sha256:d066ffc5ed0be00cd0352c95800a519cf9e4b5dd34a028d301bdc7177c72daf3 \
--hash=sha256:d9bdfa74d369256e4218000a629978590fd7cb6cf6893251dad13d051090436d \
--hash=sha256:2498762814dd7dd2a1d0248eda2afbc3dd9c11537bc8200a4b21789b6df6cd38 \
--hash=sha256:5f24ca7953f2643d59a9c87d6e272d8adddd4a53bb62b9208f36db408d7aafc7 \
--hash=sha256:5b835b86bd5a1bdbe257d610eecab07bf685b1af2a7563093e0e69180c1d4af1 \
--hash=sha256:b21650fa6907e523869e0396c5bd591cc326e5c1dd594dcdccac089561cacfb8 \
--hash=sha256:354d9fc6b1e44750e2a67b4b108841f5f5ea08853453ecbf44c81fdc2e0d50bd \
--hash=sha256:1f83e9c21cd5275991076b2ba1cd35418af3504667affb4745b48937e214bafe \
--hash=sha256:61e1a064906ccba038aa3c4a5a82f6199749efbbb3cef0804ae5c37f550eded0 \
--hash=sha256:28c659878f684365d53cf59dc9a1929ea2eecd7ac65da762be8b1ba193f7e84f \
--hash=sha256:b0ed6ad6c9640671689c2dbe6244680fe8b897c08fd1fab2228429b66c518e5e \
--hash=sha256:b3f7e671fb19734c872566e57ce7fc235fa953d7c181bb4ef138e17d607dc8a1 \
--hash=sha256:87fa943e8bbe40c8c1ba4086971a6fefbf75e9991217c55ed1bcb2f1985bd3d4 \
--hash=sha256:4775a574e9d84e0212f5b18886cace049a42e13e12009bb0491562a48bb2b758 \
--hash=sha256:9d57677238a0c5411c76097b8b93bdebb02eb845814c90f0b01727527a179e4d \
--hash=sha256:00108411e0f34c52ce16f81f1d308a571df7784932cc7491d1e94be2ee93374b \
--hash=sha256:d332eecf307fca852d02b63f35a7872de32d5ba8b4ec32da82f45df986b39ff6 \
--hash=sha256:01f799def9b96a8ec1ef6b9c1bbaf2bbc859b87545efbecc4a78faea13d0e3a0 \
--hash=sha256:47045ed35481e857918ae78b54891fac0c1d197f22c95778e66302668309336c \
--hash=sha256:2eca15d6b947cfff51ed76b2d60fd172c6ecd418ddab1c5126032d27f74bc350 \
--hash=sha256:bb36fbb48b22985d13a6b496ea5fb9bb2a076fea943831643836c9f6febbcfdc \
--hash=sha256:8323a43bd9c91f62bb7d4be74cc9ff10090e7ef820e27bfe8815c57e68261311
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" \
--hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \
--hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88
xlwt==1.3.0; python_version >= "3.7" and python_full_version < "4.0.0" \
--hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \
--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
zipp==3.8.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
--hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099 \
--hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad

View file

@ -75,8 +75,8 @@ MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': '__APP__',
'USER': '__APP__',
'NAME': '__DB_NAME__',
'USER': '__DB_USER__',
'PASSWORD': '__DB_PWD__',
'HOST': '127.0.0.1',
'PORT': '5432', # Default Postgres Port

View file

@ -4,25 +4,15 @@ from django.contrib import admin
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)
# from django_yunohost_integration.views import request_media_debug_view
if settings.PATH_URL:
# settings.PATH_URL is the $YNH_APP_ARG_PATH
# Prefix all urls with "PATH_URL":
urlpatterns = [
# path(f'{settings.PATH_URL}/debug/', debug_view),
path(f'{settings.PATH_URL}/', admin.site.urls),
# path(f'{settings.PATH_URL}/debug/', request_media_debug_view),
# TODO: https://github.com/jedie/django-for-runners/issues/25
# MEDIA_URL contains the "PATH_URL" already:

16
doc/DESCRIPTION.md Normal file
View file

@ -0,0 +1,16 @@
![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/).
[![pytest](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-for-runners_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](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)
![django-for-runners @ PyPi](https://img.shields.io/pypi/v/django-for-runners?label=django-for-runners%20%40%20PyPi)
![Python Versions](https://img.shields.io/pypi/pyversions/django-for-runners)
![License GPL V3+](https://img.shields.io/pypi/l/django-for-runners)
Pull requests welcome ;)
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
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)

152
doc/DISCLAIMER.md Normal file
View file

@ -0,0 +1,152 @@
## Settings and upgrades
Almost everything related to django-for-runners's configuration is handled in a `"../conf/settings.py"` file.
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
## SSO authentication
[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django_ynh](https://github.com/YunoHost-Apps/django_ynh):
* First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user
* All new users will be created as normal users
* Login via SSO is fully supported
* User Email, First / Last name will be updated from SSO data
## Links
* Report a bug about this package: https://github.com/YunoHost-Apps/django-for-runners_ynh
* Report a bug about django-for-runners itself: https://github.com/jedie/django-for-runners
* YunoHost website: https://yunohost.org/
---
# Developer info
## package installation / debugging
Please send your pull request to https://github.com/YunoHost-Apps/django-for-runners_ynh
Try 'main' branch, e.g.:
```bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/master --debug
or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/master --debug
```
Try 'testing' branch, e.g.:
```bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
```
To remove call e.g.:
```bash
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.:
```bash
root@yunohost:~# ls -la /var/www/django-for-runners/
total 18
drwxr-xr-x 4 root root 4 Dec 8 08:36 .
drwxr-xr-x 6 root root 6 Dec 8 08:36 ..
drwxr-xr-x 2 root root 2 Dec 8 08:36 media
drwxr-xr-x 7 root root 8 Dec 8 08:40 static
root@yunohost:~# ls -la /opt/yunohost/django-for-runners/
total 58
drwxr-xr-x 5 django-for-runners django-for-runners 11 Dec 8 08:39 .
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
-rw-r--r-- 1 django-for-runners django-for-runners 460 Dec 8 08:39 gunicorn.conf.py
-rw-r--r-- 1 django-for-runners django-for-runners 0 Dec 8 08:39 local_settings.py
-rwxr-xr-x 1 django-for-runners django-for-runners 274 Dec 8 08:39 manage.py
-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
-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 settings.py
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 check
django-for-runners v0.8.2 (Django v2.2.17)
DJANGO_SETTINGS_MODULE='settings'
PROJECT_PATH:/opt/yunohost/django-for-runners/venv/lib/python3.7/site-packages
BASE_PATH:/opt/yunohost/django-for-runners
System check identified no issues (0 silenced).
root@yunohost:~# tail -f /var/log/django-for-runners/django-for-runners.log
root@yunohost:~# cat /etc/systemd/system/django-for-runners.service
root@yunohost:~# systemctl reload-or-restart django-for-runners
root@yunohost:~# journalctl --unit=for_runners --follow
```
## local test
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
and urls made for YunoHost installation.
e.g.:
```bash
~$ git clone https://github.com/YunoHost-Apps/django-for-runners_ynh.git
~$ cd django-for-runners_ynh/
~/django-for-runners_ynh$ make
install-poetry install or update poetry
install install django-for-runners via poetry
update update the sources and installation
local-test Run local_test.py to run django-for-runners_ynh locally
~/django-for-runners_ynh$ make install-poetry
~/django-for-runners_ynh$ make install
~/django-for-runners_ynh$ make local-test
```
Notes:
* SQlite database will be used
* A super user with username `test` and password `test` is created
* The page is available under `http://127.0.0.1:8000/app_path/`

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -7,6 +7,11 @@
},
"version": "0.12.1~ynh1",
"url": "https://github.com/jedie/django-for-runners",
"upstream": {
"license": "GPL-3.0",
"website": "https://github.com/jedie/django-for-runners",
"code": "https://github.com/jedie/django-for-runners"
},
"license": "GPL-3.0",
"maintainer": {
"name": "Jens Diemer",
@ -24,32 +29,18 @@
"install" : [
{
"name": "domain",
"type": "domain",
"ask": {
"en": "Choose a domain for django-for-runners",
"fr": "Choisissez un domaine pour django-for-runners"
},
"example": "domain.org"
"type": "domain"
},
{
"name": "path",
"type": "path",
"ask": {
"en": "Choose a path for django-for-runners",
"fr": "Choisissez un chemin pour django-for-runners"
},
"example": "/django-for-runners",
"default": "/django-for-runners"
},
{
"name": "admin",
"type": "user",
"ask": {
"en": "Choose an admin user for django-for-runners",
"fr": "Choisissez l'administrateur pour django-for-runners"
},
"example": "johndoe"
}
"type": "user"
}
]
}
}

1109
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,7 @@ authors = ["JensDiemer <git@jensdiemer.de>"]
license = "GPL"
[tool.poetry.dependencies]
# Keep Python 3.7 until Yunohost contains a newer Python Version ;)
python = ">=3.7,<4.0.0"
django-for-runners = ">=0.12.1"
# Note: "ynh" extras will install gunicorn, psycopg2, django-redis and django-axes
@ -22,11 +23,14 @@ tox = "*"
pytest = "*"
pytest-cov = "*"
pytest-django = "*"
pytest-darker = "*" # https://github.com/akaihola/pytest-darker
pytest-flake8 = "*"
pytest-isort = "*"
coveralls = "*"
isort = "*"
flake8 = "*"
flynt = "*"
black = "*"
darker = "*" # https://github.com/akaihola/darker
pyupgrade = "*"
[build-system]
@ -34,18 +38,33 @@ requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.darker]
src = ['.']
revision = "origin/master..."
line_length = 100
verbose = true
skip_string_normalization = true
diff = false
check = false
stdout = false
isort = true
lint = [
"flake8",
]
log_level = "INFO"
[tool.flynt]
line_length = 100
[tool.isort]
# https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format
atomic=true
line_length=120
case_sensitive=false
profile='black'
line_length=100
skip_glob=["*/htmlcov/*","*/migrations/*"]
multi_line_output=3
include_trailing_comma=true
known_first_party=["for_runners"]
no_lines_before="LOCALFOLDER"
default_section="THIRDPARTY"
sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"]
lines_after_imports=2
@ -61,7 +80,6 @@ norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov"
# --full-trace
# -p no:warnings
addopts = """
--import-mode=importlib
--reuse-db
--nomigrations
--cov=.
@ -70,19 +88,22 @@ addopts = """
--cov-report xml
--no-cov-on-fail
--showlocals
--darker
--flake8
--isort
--doctest-modules
--failed-first
--last-failed-no-failures all
--new-first
"""
# TODO: --mypy
[tool.tox]
# https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini
legacy_tox_ini = """
[tox]
isolated_build = True
envlist = py39,py38,py37
envlist = px310,py39,py38,py37
skip_missing_interpreters = True
[testenv]

View file

@ -63,7 +63,7 @@ redis_db=$(ynh_redis_get_free_db)
#=================================================
# INSTALL DEPENDENCIES
#=================================================
ynh_script_progression --message="Installing dependencies..." --weight=40
ynh_script_progression --message="Installing dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
@ -101,9 +101,14 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=80
ynh_script_progression --message="Install project via pip..." --weight=50
# Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv"
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
python3 -m venv --without-pip "${final_path}/venv"
python3 -m venv "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path"
@ -112,13 +117,15 @@ chown -R "$app:" "$final_path"
set +o nounset
source "${final_path}/venv/bin/activate"
set -o nounset
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade wheel pip
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip install --no-deps --prefer-binary -r "$final_path/requirements.txt"
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
)
#=================================================
@ -134,12 +141,16 @@ ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_f
ynh_store_file_checksum --file="$gunicorn_conf"
cp ../conf/manage.py "$final_path/manage.py"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
ynh_store_file_checksum --file="$final_path/manage.py"
chmod +x "$final_path/manage.py"
settings="$final_path/settings.py"
cp "../conf/settings.py" "$settings"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
@ -167,25 +178,21 @@ touch "$final_path/local_settings.py"
#=================================================
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
(
set +o nounset
source "${final_path}/venv/bin/activate"
set -o nounset
cd "${final_path}"
cd "$final_path" || exit
# Just for debugging:
./manage.py diffsettings
# Just for debugging:
./manage.py diffsettings
./manage.py migrate --no-input
./manage.py collectstatic --no-input
./manage.py migrate --no-input
./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail"
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail"
# Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
./manage.py check --deploy || true
# Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
./manage.py check --deploy || true
)
#=================================================
# SETUP LOGROTATE
@ -210,9 +217,13 @@ yunohost service add $app --description="Web based management to catalog things"
# Set permissions to app files
chown -R "$app:" "$log_path"
chown -R "$app:" "$public_path"
chown -R "$app:www-data" "$public_path"
chown -R "$app:" "$final_path"
chmod o-rwx "$log_path"
chmod o-rwx "$public_path"
chmod o-rwx "$final_path"
#=================================================
# SETUP SYSTEMD
#=================================================

View file

@ -70,7 +70,7 @@ ynh_system_user_create --username=$app --home_dir="$final_path" --use_shell
#=================================================
# Restore permissions on app files
chown -R "$app:" "$public_path"
chown -R "$app:www-data" "$public_path"
chown -R "$app:" "$final_path"
#=================================================
@ -78,7 +78,7 @@ chown -R "$app:" "$final_path"
#=================================================
# REINSTALL DEPENDENCIES
#=================================================
ynh_script_progression --message="Reinstalling dependencies..." --weight=40
ynh_script_progression --message="Reinstalling dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
@ -86,22 +86,29 @@ 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
ynh_script_progression --message="Upgrade Python virtualenv..." --weight=50
python3 -m venv "${final_path}/venv"
# Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv"
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
python3 -m venv --without-pip "${final_path}/venv"
chown -R "$app:" "$final_path"
#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 wheel pip
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip install --no-deps --prefer-binary -r "$final_path/requirements.txt"
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
)
#=================================================
@ -137,6 +144,21 @@ touch "${log_file}"
chown -R "$app:" "$log_path"
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
#=================================================
# GENERIC FINALIZATION
#=================================================
# SECURE FILES AND DIRECTORIES
#=================================================
# Set permissions to app files
chown -R "$app:" "$log_path"
chown -R "$app:www-data" "$public_path"
chown -R "$app:" "$final_path"
chmod o-rwx "$log_path"
chmod o-rwx "$public_path"
chmod o-rwx "$final_path"
#=================================================
# GENERIC FINALIZATION
#=================================================

View file

@ -22,7 +22,11 @@ domain=$(ynh_app_setting_get --app="$app" --key=domain)
path_url=$(ynh_app_setting_get --app="$app" --key=path)
port=$(ynh_app_setting_get --app="$app" --key=port)
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
db_name=$(ynh_sanitize_dbid --db_name="$app")
db_user=$db_name
admin_mail=$(ynh_user_get_info "$admin" mail)
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
@ -63,7 +67,7 @@ ynh_add_nginx_config "public_path" "port"
#=================================================
# Update dependencies
#=================================================
ynh_script_progression --message="Upgrading dependencies..."
ynh_script_progression --message="Upgrading dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
@ -85,9 +89,14 @@ ynh_add_systemd_config --service="$app" --template="django-for-runners.service"
#=================================================
# UPGRADE VENV
#=================================================
ynh_script_progression --message="Upgrade project via pip..." --weight=80
ynh_script_progression --message="Upgrade project via pip..." --weight=50
# Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv"
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
python3 -m venv --without-pip "${final_path}/venv"
python3 -m venv --upgrade "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path"
@ -96,13 +105,15 @@ chown -R "$app:" "$final_path"
set +o nounset
source "${final_path}/venv/bin/activate"
set -o nounset
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade wheel pip
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip install --no-deps --prefer-binary -r "$final_path/requirements.txt"
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
)
#=================================================
@ -118,8 +129,9 @@ ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf"
ynh_store_file_checksum --file="$gunicorn_conf"
ynh_backup_if_checksum_is_different --file="$final_path/manage.py"
cp ../conf/manage.py "$final_path/manage.py"
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
ynh_store_file_checksum --file="$final_path/manage.py"
chmod +x "$final_path/manage.py"
# save old settings file
@ -129,6 +141,8 @@ ynh_backup_if_checksum_is_different --file="$settings"
cp "../conf/settings.py" "$settings"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
@ -159,25 +173,21 @@ touch "$final_path/local_settings.py"
#=================================================
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
(
set +o nounset
source "${final_path}/venv/bin/activate"
set -o nounset
cd "${final_path}"
cd "$final_path" || exit
# Just for debugging:
./manage.py diffsettings
# Just for debugging:
./manage.py diffsettings
./manage.py migrate --no-input
./manage.py collectstatic --no-input
./manage.py migrate --no-input
./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail"
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail"
# Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
./manage.py check --deploy || true
# Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
./manage.py check --deploy || true
)
#=================================================
# SETUP LOGROTATE
@ -202,9 +212,13 @@ yunohost service add $app --description="Web based management to catalog things"
# Set permissions to app files
chown -R "$app:" "$log_path"
chown -R "$app:" "$public_path"
chown -R "$app:www-data" "$public_path"
chown -R "$app:" "$final_path"
chmod o-rwx "$log_path"
chmod o-rwx "$public_path"
chmod o-rwx "$final_path"
#=================================================
# Start for_runners via systemd
#=================================================

View file

@ -14,4 +14,4 @@ python3 -m venv "${final_path}/venv"
source "${final_path}/venv/bin/activate"
$final_path/venv/bin/pip install --upgrade wheel pip
$final_path/venv/bin/pip install --no-deps --prefer-binary -r "./conf/requirements.txt"
$final_path/venv/bin/pip install --no-deps -r "./conf/requirements.txt"

View file

@ -39,9 +39,9 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
# TODO: https://github.com/jedie/django-for-runners/issues/25
# Serve user uploads via django_tools.serve_media_app:
# assert settings.MEDIA_URL == '/app_path/media/'
# assert reverse('serve_media_app:serve-media', kwargs={'user_token': 'token', 'path': 'foo/bar/'}) == (
# '/app_path/media/token/foo/bar/'
# )
# assert reverse(
# 'serve_media_app:serve-media', kwargs={'user_token': 'token', 'path': 'foo/bar/'}
# ) == ('/app_path/media/token/foo/bar/')
def test_auth(self):
# SecurityMiddleware should redirects all non-HTTPS requests to HTTPS:
@ -51,14 +51,12 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
response,
status_code=301, # permanent redirect
expected_url='https://testserver/app_path/',
fetch_redirect_response=False
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
response, expected_url='/app_path/login/?next=/app_path/', fetch_redirect_response=False
)
@override_settings(SECURE_SSL_REDIRECT=False)
@ -150,7 +148,9 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
path='/app_path/',
HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='test',
HTTP_AUTHORIZATION=generate_basic_auth(username='foobar', password='test123'), # <<< wrong user name
HTTP_AUTHORIZATION=generate_basic_auth(
username='foobar', password='test123'
), # <<< wrong user name
)
assert User.objects.count() == 1

View file

@ -1,13 +0,0 @@
import shutil
import subprocess
from pathlib import Path
BASE_PATH = Path(__file__).parent.parent
def test_lint():
assert Path(BASE_PATH, 'Makefile').is_file()
make_bin = shutil.which('make')
assert make_bin is not None
subprocess.check_call([make_bin, 'lint'], cwd=BASE_PATH)

View file

@ -4,7 +4,8 @@ import shutil
import subprocess
from pathlib import Path
from bx_py_utils.path import assert_is_file
from bx_django_utils.filename import clean_filename
from bx_py_utils.path import assert_is_dir, assert_is_file
import for_runners
@ -23,8 +24,12 @@ def assert_file_contains_string(file_path, string):
def test_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, 'manifest.json'), 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, 'manifest.json'), string=f'"version": "{version}~ynh'
)
def poetry_check_output(*args):
@ -32,7 +37,7 @@ def poetry_check_output(*args):
output = subprocess.check_output(
(poerty_bin,) + args,
universal_newlines=True,
text=True,
env=os.environ,
stderr=subprocess.STDOUT,
cwd=str(PACKAGE_ROOT),
@ -57,9 +62,28 @@ def test_requirements_txt():
diff = '\n'.join(
difflib.unified_diff(
current_content.splitlines(), output.splitlines(),
fromfile=str(requirements_txt), tofile='FRESH EXPORT'
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")'
def test_screenshot_filenames():
"""
https://forum.yunohost.org/t/yunohost-bot-cant-handle-spaces-in-screenshots/19483
"""
screenshot_path = PACKAGE_ROOT / 'doc' / 'screenshots'
assert_is_dir(screenshot_path)
renamed = []
for file_path in screenshot_path.iterdir():
file_name = file_path.name
cleaned_name = clean_filename(file_name)
if cleaned_name != file_name:
new_path = file_path.with_name(cleaned_name)
file_path.rename(new_path)
renamed.append(f'{file_name!r} renamed to {cleaned_name!r}')
assert not renamed, f'Bad screenshots file names found: {", ".join(renamed)}'