diff --git a/.editorconfig b/.editorconfig index 0f4b35f..341d20b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,7 +10,7 @@ trim_trailing_whitespace = true insert_final_newline = true [*.py] -line_length = 119 +max_line_length = 100 [{Makefile,**.mk}] indent_style = tab @@ -18,4 +18,3 @@ insert_final_newline = false [*.yml] indent_style = tab -indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..2729a6b --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,55 @@ +--- +name: Bug report +about: When creating a bug report, please use the following template to provide all the relevant information and help debugging efficiently. + +--- + +**How to post a meaningful bug report** +1. *Read this whole template first.* +2. *Determine if you are on the right place:* + - *If you were performing an action on the app from the webadmin or the CLI (install, update, backup, restore, change_url...), you are on the right place!* + - *Otherwise, the issue may be due to the app itself. Refer to its documentation or repository for help.* + - *When in doubt, post here and we will figure it out together.* +3. *Delete the italic comments as you write over them below, and remove this guide.* +--- + +### Describe the bug + +*A clear and concise description of what the bug is.* + +### Context + +- Hardware: *VPS bought online / Old laptop or computer / Raspberry Pi at home / Internet Cube with VPN / Other ARM board / ...* +- YunoHost version: x.x.x +- I have access to my server: *Through SSH | through the webadmin | direct access via keyboard / screen | ...* +- Are you in a special context or did you perform some particular tweaking on your YunoHost instance?: *no / yes* + - If yes, please explain: +- Using, or trying to install package version/branch: +- If upgrading, current package version: *can be found in the admin, or with `yunohost app info $app_id`* + +### Steps to reproduce + +- *If you performed a command from the CLI, the command itself is enough. For example:* + ```sh + sudo yunohost app install the_app + ``` +- *If you used the webadmin, please perform the equivalent command from the CLI first.* +- *If the error occurs in your browser, explain what you did:* + 1. *Go to '...'* + 2. *Click on '...'* + 3. *Scroll down to '...'* + 4. *See error* + +### Expected behavior + +*A clear and concise description of what you expected to happen. You can remove this section if the command above is enough to understand your intent.* + +### Logs + +*When an operation fails, YunoHost provides a simple way to share the logs.* +- *In the webadmin, the error message contains a link to the relevant log page. On that page, you will be able to 'Share with Yunopaste'. If you missed it, the logs of previous operations are also available under Tools > Logs.* +- *In command line, the command to share the logs is displayed at the end of the operation and looks like `yunohost log display [log name] --share`. If you missed it, you can find the log ID of a previous operation using `yunohost log list`.* + +*After sharing the log, please copypaste directly the link provided by YunoHost (to help readability, no need to copypaste the entire content of the log here, just the link is enough...)* + +*If applicable and useful, add screenshots to help explain your problem.* diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..ef70e18 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,16 @@ +## Problem + +- *Description of why you made this PR* + +## Solution + +- *And how do you fix that problem* + +## PR Status + +- [ ] Code finished and ready to be reviewed/tested +- [ ] The fix/enhancement were manually tested (if applicable) + +## Automatic tests + +Automatic tests can be triggered on https://ci-apps-dev.yunohost.org/ *after creating the PR*, by commenting "!testme", "!gogogadgetoci" or "By the power of systemd, I invoke The Great App CI to test this Pull Request!". (N.B. : for this to work you need to be a member of the Yunohost-Apps organization) diff --git a/.github/workflows/package_linter.yml b/.github/workflows/package_linter.yml index 9498bca..6126a95 100644 --- a/.github/workflows/package_linter.yml +++ b/.github/workflows/package_linter.yml @@ -1,9 +1,12 @@ name: YunoHost apps package linter on: + push: + branches: + - main + pull_request: schedule: - cron: '0 8 * * *' - push: jobs: test: diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index e190805..6e1050a 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -1,9 +1,12 @@ name: pytest on: + push: + branches: + - master + pull_request: schedule: - cron: '0 8 * * *' - push: jobs: test: @@ -11,11 +14,16 @@ 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 + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'fetch master' + run: | + git fetch origin master - name: 'Set up Python ${{ matrix.python-version }}' - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: '${{ matrix.python-version }}' @@ -33,9 +41,7 @@ jobs: make pytest - name: 'Upload coverage report' - run: bash <(curl -s https://codecov.io/bash) - - - name: 'Run linters' - if: matrix.python-version == '3.8' - run: | - make lint + uses: codecov/codecov-action@v2 + with: + fail_ci_if_error: false + verbose: true diff --git a/.gitignore b/.gitignore index d4aff27..3462408 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ !.editorconfig !.flake8 !.gitignore +!/doc/screenshots/.gitkeep __pycache__ secret.txt /local_test/ diff --git a/Makefile b/Makefile index 3692cc4..7e8b78f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ SHELL := /bin/bash -MAX_LINE_LENGTH := 119 +MAX_LINE_LENGTH := 100 all: help @@ -29,12 +29,12 @@ update: install-poetry ## update the sources and installation and generate "con 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 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 flynt --line-length=${MAX_LINE_LENGTH} . poetry run black --verbose --safe --line-length=${MAX_LINE_LENGTH} --skip-string-normalization . poetry run isort . diff --git a/README.md b/README.md index d68ff6b..c301584 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,19 @@ -# django_example_ynh + + +# Django Example for YunoHost + +[![Integration level](https://dash.yunohost.org/integration/django_example_ynh.svg)](https://dash.yunohost.org/appci/app/django_example_ynh) ![Working status](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.status.svg) ![Maintenance status](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.maintain.svg) +[![Install Django Example with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django_example_ynh) + +*[Lire ce readme en français.](./README_fr.md)* + +> *This package allows you to install Django Example 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.* + +## Overview [![pytest](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml) @@ -11,6 +26,10 @@ Demo [YunoHost Application](https://install-app.yunohost.org/?app=django_example Pull requests welcome ;) +**Shipped version:** 0.3.0~ynh1 + +## Disclaimers / important information + ## local test For quicker developing of django_example_ynh in the context of YunoHost app, @@ -88,22 +107,21 @@ These projects used `django_example_ynh`: # Developer info +The App project will be stored under `__FINALPATH__` (e.g.: `/opt/yunohost/$app`) that's Django's `settings.FINALPATH` +"static" / "media" files to serve via nginx are under `__PUBLIC_PATH__` (e.g.: `/var/www/$app`) that's `settings.PUBLIC_PATH` + ## package installation / debugging -Please send your pull request to https://github.com/YunoHost-Apps/django_example_ynh - -Try 'main' branch, e.g.: +This app is not in YunoHost app catalog. Test install, e.g.: ```bash -sudo yunohost app install https://github.com/YunoHost-Apps/django_example_ynh/tree/master --debug -or -sudo yunohost app upgrade django_example_ynh -u https://github.com/YunoHost-Apps/django_example_ynh/tree/master --debug +~# git clone https://github.com/YunoHost-Apps/django_example_ynh.git +~# yunohost app install django_example_ynh/ -f ``` - -Try 'testing' branch, e.g.: +To update: ```bash -sudo yunohost app install https://github.com/YunoHost-Apps/django_example_ynh/tree/testing --debug -or -sudo yunohost app upgrade django_example_ynh -u https://github.com/YunoHost-Apps/django_example_ynh/tree/testing --debug +~# cd django_example_ynh +~/django_example_ynh# git fetch && git reset --hard origin/testing +~/django_example_ynh# yunohost app upgrade django_example_ynh -u . -F ``` To remove call e.g.: @@ -122,7 +140,7 @@ yunohost app remove django_example_ynh yunohost backup restore 20201223-163434 --apps django_example_ynh ``` -Debug installation, e.g.: +Debug the installation, e.g.: ```bash root@yunohost:~# ls -la /var/www/django_example_ynh/ total 18 @@ -153,10 +171,33 @@ BASE_PATH:/opt/yunohost/django_example_ynh System check identified no issues (0 silenced). root@yunohost:~# tail -f /var/log/django_example_ynh/django_example_ynh.log -root@yunohost:~# cat /etc/systemd/system/django_example_ynh.service +root@yunohost:~# cat /etc/systemd/system/systemd.service root@yunohost:~# systemctl reload-or-restart django_example_ynh root@yunohost:~# journalctl --unit=django_example_ynh --follow ``` + +## Documentation and resources + +* Official app website: +* Official user documentation: +* Official admin documentation: +* Upstream app code repository: +* YunoHost documentation for this app: +* Report a bug: + +## Developer info + +Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing). + +To try the testing branch, please proceed like that. + +``` bash +sudo yunohost app install https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing --debug +or +sudo yunohost app upgrade django_example_ynh -u https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing --debug +``` + +**More info regarding app packaging:** diff --git a/README_fr.md b/README_fr.md new file mode 100644 index 0000000..6d2d5dd --- /dev/null +++ b/README_fr.md @@ -0,0 +1,203 @@ + + +# Django Example pour YunoHost + +[![Niveau d'intégration](https://dash.yunohost.org/integration/django_example_ynh.svg)](https://dash.yunohost.org/appci/app/django_example_ynh) ![Statut du fonctionnement](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.status.svg) ![Statut de maintenance](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.maintain.svg) +[![Installer Django Example avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django_example_ynh) + +*[Read this readme in english.](./README.md)* + +> *Ce package vous permet d'installer Django Example 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 + +[![pytest](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml) + +Demo [YunoHost Application](https://install-app.yunohost.org/?app=django_example_ynh) to demonstrate the integration of a Django project under YunoHost. + +[![Integration level](https://dash.yunohost.org/integration/django_example_ynh.svg)](https://dash.yunohost.org/appci/app/django_example_ynh) ![](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.maintain.svg) +[![Install django_example_ynh with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django_example_ynh) + + +Pull requests welcome ;) + + +**Version incluse :** 0.3.0~ynh1 + +## Avertissements / informations importantes + +## local test + +For quicker developing of django_example_ynh 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_example_ynh.git +~$ cd django_example_ynh/ +~/django_example_ynh$ make +install-poetry install or update poetry +install install project via poetry +update update the sources and installation and generate "conf/requirements.txt" +lint Run code formatters and linter +fix-code-style Fix code formatting +tox-listenvs List all tox test environments +tox Run pytest via tox with all environments +pytest Run pytest +publish Release new version to PyPi +local-test Run local_test.py to run the project locally +local-diff-settings Run "manage.py diffsettings" with local test + +~/django_example_ynh$ make install-poetry +~/django_example_ynh$ make install +~/django_example_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/` + + +## history + +* [compare v0.1.5...master](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.2.0...master) **dev** + * tbc +* [v0.2.0 - 15.09.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.5...v0.2.0) + * rename/split `django_example_ynh` into: + * [django_yunohost_integration](https://github.com/jedie/django_yunohost_integration) - Python package with the glue code to integrate a Django project with YunoHost + * [django_example_ynh](https://github.com/YunoHost-Apps/django_example_ynh) - Demo YunoHost App to demonstrate the integration of a Django project under YunoHost +* [v0.1.5 - 19.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.4...v0.1.5) + * Make some deps `gunicorn`, `psycopg2-binary`, `django-redis`, `django-axes` optional +* [v0.1.4 - 08.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.3...v0.1.4) + * Bugfix [CSRF verification failed on POST requests #7](https://github.com/YunoHost-Apps/django_example_ynh/issues/7) +* [v0.1.3 - 08.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.2...v0.1.3) + * set "DEBUG = True" in local_test (so static files are served and auth works) + * Bugfixes and cleanups +* [v0.1.2 - 29.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.1...v0.1.2) + * Bugfixes +* [v0.1.1 - 29.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.0...v0.1.1) + * Refactor "create_superuser" to a manage command, useable via "django_example_ynh" in `INSTALLED_APPS` + * Generate "conf/requirements.txt" and use this file for install + * rename own settings and urls (in `/conf/`) +* [v0.1.0 - 28.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/f578f14...v0.1.0) + * first working state +* [23.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/commit/f578f144a3a6d11d7044597c37d550d29c247773) + * init the project + + +## Links + +* Report a bug about this package: https://github.com/YunoHost-Apps/django_example_ynh +* YunoHost website: https://yunohost.org/ +* PyPi package: https://pypi.org/project/django-ynh/ + +These projects used `django_example_ynh`: + +* https://github.com/YunoHost-Apps/django_example_ynh +* https://github.com/YunoHost-Apps/django-for-runners_ynh + +--- + +# Developer info + +The App project will be stored under `__FINALPATH__` (e.g.: `/opt/yunohost/$app`) that's Django's `settings.FINALPATH` +"static" / "media" files to serve via nginx are under `__PUBLIC_PATH__` (e.g.: `/var/www/$app`) that's `settings.PUBLIC_PATH` + +## package installation / debugging + +This app is not in YunoHost app catalog. Test install, e.g.: +```bash +~# git clone https://github.com/YunoHost-Apps/django_example_ynh.git +~# yunohost app install django_example_ynh/ -f +``` +To update: +```bash +~# cd django_example_ynh +~/django_example_ynh# git fetch && git reset --hard origin/testing +~/django_example_ynh# yunohost app upgrade django_example_ynh -u . -F +``` + +To remove call e.g.: +```bash +sudo yunohost app remove django_example_ynh +``` + +Backup / remove / restore cycle, e.g.: +```bash +yunohost backup create --apps django_example_ynh +yunohost backup list +archives: + - django_example_ynh-pre-upgrade1 + - 20201223-163434 +yunohost app remove django_example_ynh +yunohost backup restore 20201223-163434 --apps django_example_ynh +``` + +Debug the installation, e.g.: +```bash +root@yunohost:~# ls -la /var/www/django_example_ynh/ +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_example_ynh/ +total 58 +drwxr-xr-x 5 django_example_ynh django_example_ynh 11 Dec 8 08:39 . +drwxr-xr-x 3 root root 3 Dec 8 08:36 .. +-rw-r--r-- 1 django_example_ynh django_example_ynh 460 Dec 8 08:39 gunicorn.conf.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 0 Dec 8 08:39 local_settings.py +-rwxr-xr-x 1 django_example_ynh django_example_ynh 274 Dec 8 08:39 manage.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 171 Dec 8 08:39 secret.txt +drwxr-xr-x 6 django_example_ynh django_example_ynh 6 Dec 8 08:37 venv +-rw-r--r-- 1 django_example_ynh django_example_ynh 115 Dec 8 08:39 wsgi.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 4737 Dec 8 08:39 django_example_ynh_demo_settings.py + +root@yunohost:~# cd /opt/yunohost/django_example_ynh/ +root@yunohost:/opt/yunohost/django_example_ynh# source venv/bin/activate +(venv) root@yunohost:/opt/yunohost/django_example_ynh# ./manage.py check +django_example_ynh v0.8.2 (Django v2.2.17) +DJANGO_SETTINGS_MODULE='django_example_ynh_demo_settings' +PROJECT_PATH:/opt/yunohost/django_example_ynh/venv/lib/python3.7/site-packages +BASE_PATH:/opt/yunohost/django_example_ynh +System check identified no issues (0 silenced). + +root@yunohost:~# tail -f /var/log/django_example_ynh/django_example_ynh.log +root@yunohost:~# cat /etc/systemd/system/systemd.service + +root@yunohost:~# systemctl reload-or-restart django_example_ynh +root@yunohost:~# journalctl --unit=django_example_ynh --follow +``` + + + +## Documentations et ressources + +* Site officiel de l'app : +* Documentation officielle utilisateur : +* Documentation officielle de l'admin : +* Dépôt de code officiel de l'app : +* Documentation YunoHost pour cette app : +* Signaler un bug : + +## Informations pour les développeurs + +Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing). + +Pour essayer la branche testing, procédez comme suit. + +``` bash +sudo yunohost app install https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing --debug +ou +sudo yunohost app upgrade django_example_ynh -u https://github.com/YunoHost-Apps/django_example_ynh_ynh/tree/testing --debug +``` + +**Plus d'infos sur le packaging d'applications :** diff --git a/conf/gunicorn.conf.py b/conf/gunicorn.conf.py index bcab967..f49a397 100644 --- a/conf/gunicorn.conf.py +++ b/conf/gunicorn.conf.py @@ -17,4 +17,4 @@ accesslog = '__LOG_FILE__' errorlog = '__LOG_FILE__' # https://docs.gunicorn.org/en/latest/settings.html#pidfile -pidfile = '__FINAL_HOME_PATH__/gunicorn.pid' +pidfile = '__FINALPATH__/gunicorn.pid' diff --git a/conf/manage.py b/conf/manage.py index a85e3b1..ec26808 100755 --- a/conf/manage.py +++ b/conf/manage.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!__FINALPATH__/venv/bin/python import os import sys diff --git a/conf/nginx.conf b/conf/nginx.conf index 7a1d5fb..867d5ef 100644 --- a/conf/nginx.conf +++ b/conf/nginx.conf @@ -1,6 +1,7 @@ location __PATH__/static/ { - # Django static files + # Service static files by nginx + # e.g.: /var/www/$app/static alias __PUBLIC_PATH__/static/; expires 30d; } diff --git a/conf/requirements.txt b/conf/requirements.txt index b2e2c47..8c4aff5 100644 --- a/conf/requirements.txt +++ b/conf/requirements.txt @@ -1,65 +1,128 @@ -asgiref==3.3.1; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:5ee950735509d04eb673bd7f7120f8fa1c9e2df495394992c73234d526907e17 \ - --hash=sha256:7162a3cb30ab0609f1a4c95938fd73e8604f63bdba516a7f7d64b83ff09478f0 -django-axes==5.13.1; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ - --hash=sha256:8f7870dc18ace6155127073bffe7276719c71c5ad4e67b45abedc0207f64a2f6 \ - --hash=sha256:aef814f738742b01cc7730cd2bebe3e5b462b807fd6c2ed609b62437ccc71f80 -django-ipware==3.0.2; python_version >= "3.7" and python_version < "4.0" and python_full_version < "4.0.0" \ - --hash=sha256:c7df8e1410a8e5d6b1fbae58728402ea59950f043c3582e033e866f0f0cf5e94 -django-redis==4.12.1; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:306589c7021e6468b2656edc89f62b8ba67e8d5a1c8877e2688042263daa7a63 \ - --hash=sha256:1133b26b75baa3664164c3f44b9d5d133d1b8de45d94d79f38d1adc5b1d502e5 -django-yunohost-integration==0.2.0a0; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:a45197a3c4595a496674e7e48a58f58351b6022526893264831e0d6ba463a44f \ - --hash=sha256:9acdf320537ccce47ceb1d51d2a00fafbf30938152d3b22c59a3a2ead7952227 -django==3.1.7; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "4.0" \ - --hash=sha256:baf099db36ad31f970775d0be5587cc58a6256a6771a44eb795b554d45f211b8 \ - --hash=sha256:32ce792ee9b6a0cbbec340123e229ac9f765dff8c2a4ae9247a14b2ba3a365a7 -gunicorn==20.0.4; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c \ - --hash=sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626 -psycopg2-binary==2.8.6; 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.4.0" \ - --hash=sha256:11b9c0ebce097180129e422379b824ae21c8f2a6596b159c7659e2e5a00e1aa0 \ - --hash=sha256:d14b140a4439d816e3b1229a4a525df917d6ea22a0771a2a78332273fd9528a4 \ - --hash=sha256:1fabed9ea2acc4efe4671b92c669a213db744d2af8a9fc5d69a8e9bc14b7a9db \ - --hash=sha256:f5ab93a2cb2d8338b1674be43b442a7f544a0971da062a5da774ed40587f18f5 \ - --hash=sha256:b4afc542c0ac0db720cf516dd20c0846f71c248d2b3d21013aa0d4ef9c71ca25 \ - --hash=sha256:e74a55f6bad0e7d3968399deb50f61f4db1926acf4a6d83beaaa7df986f48b1c \ - --hash=sha256:0deac2af1a587ae12836aa07970f5cb91964f05a7c6cdb69d8425ff4c15d4e2c \ - --hash=sha256:ad20d2eb875aaa1ea6d0f2916949f5c08a19c74d05b16ce6ebf6d24f2c9f75d1 \ - --hash=sha256:950bc22bb56ee6ff142a2cb9ee980b571dd0912b0334aa3fe0fe3788d860bea2 \ - --hash=sha256:b8a3715b3c4e604bcc94c90a825cd7f5635417453b253499664f784fc4da0152 \ - --hash=sha256:d1b4ab59e02d9008efe10ceabd0b31e79519da6fb67f7d8e8977118832d0f449 \ - --hash=sha256:ac0c682111fbf404525dfc0f18a8b5f11be52657d4f96e9fcb75daf4f3984859 \ - --hash=sha256:7d92a09b788cbb1aec325af5fcba9fed7203897bbd9269d5691bb1e3bce29550 \ - --hash=sha256:aaa4213c862f0ef00022751161df35804127b78adf4a2755b9f991a507e425fd \ - --hash=sha256:c2507d796fca339c8fb03216364cca68d87e037c1f774977c8fc377627d01c71 \ - --hash=sha256:ee69dad2c7155756ad114c02db06002f4cded41132cc51378e57aad79cc8e4f4 \ - --hash=sha256:e82aba2188b9ba309fd8e271702bd0d0fc9148ae3150532bbb474f4590039ffb \ - --hash=sha256:d5227b229005a696cc67676e24c214740efd90b148de5733419ac9aaba3773da \ - --hash=sha256:a0eb43a07386c3f1f1ebb4dc7aafb13f67188eab896e7397aa1ee95a9c884eb2 \ - --hash=sha256:e1f57aa70d3f7cc6947fd88636a481638263ba04a742b4a37dd25c373e41491a \ - --hash=sha256:833709a5c66ca52f1d21d41865a637223b368c0ee76ea54ca5bad6f2526c7679 \ - --hash=sha256:ba28584e6bca48c59eecbf7efb1576ca214b47f05194646b081717fa628dfddf \ - --hash=sha256:6a32f3a4cb2f6e1a0b15215f448e8ce2da192fd4ff35084d80d5e39da683e79b \ - --hash=sha256:0e4dc3d5996760104746e6cfcdb519d9d2cd27c738296525d5867ea695774e67 \ - --hash=sha256:cec7e622ebc545dbb4564e483dd20e4e404da17ae07e06f3e780b2dacd5cee66 \ - --hash=sha256:ba381aec3a5dc29634f20692349d73f2d21f17653bda1decf0b52b11d694541f \ - --hash=sha256:a0c50db33c32594305b0ef9abc0cb7db13de7621d2cadf8392a1d9b3c437ef77 \ - --hash=sha256:2dac98e85565d5688e8ab7bdea5446674a83a3945a8f416ad0110018d1501b94 \ - --hash=sha256:bd1be66dde2b82f80afb9459fc618216753f67109b859a361cf7def5c7968729 \ - --hash=sha256:8cd0fb36c7412996859cb4606a35969dd01f4ea34d9812a141cd920c3b18be77 \ - --hash=sha256:89705f45ce07b2dfa806ee84439ec67c5d9a0ef20154e0e475e2b2ed392a5b83 \ - --hash=sha256:42ec1035841b389e8cc3692277a0bd81cdfe0b65d575a2c8862cec7a80e62e52 \ - --hash=sha256:7312e931b90fe14f925729cde58022f5d034241918a5c4f9797cac62f6b3a9dd \ - --hash=sha256:6422f2ff0919fd720195f64ffd8f924c1395d30f9a495f31e2392c2efafb5056 \ - --hash=sha256:15978a1fbd225583dd8cdaf37e67ccc278b5abecb4caf6b2d6b8e2b948e953f6 -pytz==2021.1; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798 \ - --hash=sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da -redis==3.5.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ - --hash=sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24 \ - --hash=sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2 -sqlparse==0.4.1; python_version >= "3.7" and python_full_version < "4.0.0" \ - --hash=sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0 \ - --hash=sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8 +asgiref==3.5.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4 \ + --hash=sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424 +async-timeout==4.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15 \ + --hash=sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c +deprecated==1.2.13; 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.4.0" \ + --hash=sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d \ + --hash=sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d +django-axes==5.36.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:bac08a7047fde26ffb54813c971fd40eeadb4ecb8d342a6e47d53de666d1a792 \ + --hash=sha256:466e6ed1affd0866c78f245ee658d2619f74250aca5856852d86e61dba400eda +django-ipware==4.0.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \ + --hash=sha256:602a58325a4808bd19197fef2676a0b2da2df40d0ecf21be414b2ff48c72ad05 \ + --hash=sha256:878dbb06a87e25550798e9ef3204ed70a200dd8b15e47dcef848cf08244f04c9 +django-redis==5.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de \ + --hash=sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026 +django-yunohost-integration==0.2.5; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:b5f9beea73515ffb8816644cde766cdd0170ce75441ceb9ac11e185f40470186 \ + --hash=sha256:2cade1dc6d77974139624883475dfe360fe04a86335b635f1fac2401acae56d8 +django==3.2.15; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713 \ + --hash=sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b +gunicorn==20.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \ + --hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8 +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 +packaging==21.3; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 \ + --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb +psycopg2==2.9.3; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362 \ + --hash=sha256:d3ca6421b942f60c008f81a3541e8faf6865a28d5a9b48544b0ee4f40cac7fca \ + --hash=sha256:9572e08b50aed176ef6d66f15a21d823bb6f6d23152d35e8451d7d2d18fdac56 \ + --hash=sha256:a81e3866f99382dfe8c15a151f1ca5fde5815fde879348fe5a9884a7c092a305 \ + --hash=sha256:cb10d44e6694d763fa1078a26f7f6137d69f555a78ec85dc2ef716c37447e4b2 \ + --hash=sha256:4295093a6ae3434d33ec6baab4ca5512a5082cc43c0505293087b8a46d108461 \ + --hash=sha256:34b33e0162cfcaad151f249c2649fd1030010c16f4bbc40a604c1cb77173dcf7 \ + --hash=sha256:0762c27d018edbcb2d34d51596e4346c983bd27c330218c56c4dc25ef7e819bf \ + --hash=sha256:8cf3878353cc04b053822896bc4922b194792df9df2f1ad8da01fb3043602126 \ + --hash=sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c \ + --hash=sha256:8e841d1bf3434da985cc5ef13e6f75c8981ced601fd70cc6bf33351b91562981 +pyparsing==3.0.9; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.8" \ + --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc \ + --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb +pytz==2022.2.1; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197 \ + --hash=sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5 +redis==4.3.4; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54 \ + --hash=sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880 +sqlparse==0.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \ + --hash=sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d \ + --hash=sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae +typing-extensions==4.3.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \ + --hash=sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02 \ + --hash=sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6 +wrapt==1.14.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \ + --hash=sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3 \ + --hash=sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef \ + --hash=sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28 \ + --hash=sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59 \ + --hash=sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87 \ + --hash=sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1 \ + --hash=sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b \ + --hash=sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462 \ + --hash=sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1 \ + --hash=sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320 \ + --hash=sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2 \ + --hash=sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4 \ + --hash=sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069 \ + --hash=sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310 \ + --hash=sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f \ + --hash=sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656 \ + --hash=sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c \ + --hash=sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8 \ + --hash=sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164 \ + --hash=sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907 \ + --hash=sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3 \ + --hash=sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3 \ + --hash=sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d \ + --hash=sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7 \ + --hash=sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00 \ + --hash=sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4 \ + --hash=sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1 \ + --hash=sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1 \ + --hash=sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff \ + --hash=sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d \ + --hash=sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1 \ + --hash=sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569 \ + --hash=sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed \ + --hash=sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471 \ + --hash=sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248 \ + --hash=sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68 \ + --hash=sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d \ + --hash=sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77 \ + --hash=sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7 \ + --hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \ + --hash=sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a \ + --hash=sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853 \ + --hash=sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c \ + --hash=sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456 \ + --hash=sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f \ + --hash=sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc \ + --hash=sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1 \ + --hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af \ + --hash=sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b \ + --hash=sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0 \ + --hash=sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57 \ + --hash=sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5 \ + --hash=sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d \ + --hash=sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383 \ + --hash=sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7 \ + --hash=sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86 \ + --hash=sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735 \ + --hash=sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b \ + --hash=sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3 \ + --hash=sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3 \ + --hash=sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe \ + --hash=sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5 \ + --hash=sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb \ + --hash=sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d +zipp==3.8.1; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \ + --hash=sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009 \ + --hash=sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2 diff --git a/conf/settings.py b/conf/settings.py index b6e32f2..a1daedc 100644 --- a/conf/settings.py +++ b/conf/settings.py @@ -2,7 +2,7 @@ ################################################################################ # Please do not modify this file, it will be reset at the next update. -# You can edit the file __FINAL_HOME_PATH__/local_settings.py and add/modify the settings you need. +# You can edit the file __FINALPATH__/local_settings.py and add/modify the settings you need. # The parameters you add in local_settings.py will overwrite these, # but you can use the options and documentation in this file to find out what can be done. @@ -11,19 +11,19 @@ from pathlib import Path as __Path -from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret from django_yunohost_integration.base_settings import * # noqa +from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret DEBUG = False # Don't turn DEBUG on in production! # ----------------------------------------------------------------------------- -FINAL_HOME_PATH = __Path('__FINAL_HOME_PATH__') # /opt/yunohost/$app -assert FINAL_HOME_PATH.is_dir(), f'Directory not exists: {FINAL_HOME_PATH}' +FINALPATH = __Path('__FINALPATH__') # /opt/yunohost/$app +assert FINALPATH.is_dir(), f'Directory not exists: {FINALPATH}' -FINAL_WWW_PATH = __Path('__FINAL_WWW_PATH__') # /var/www/$app -assert FINAL_WWW_PATH.is_dir(), f'Directory not exists: {FINAL_WWW_PATH}' +PUBLIC_PATH = __Path('__PUBLIC_PATH__') # /var/www/$app +assert PUBLIC_PATH.is_dir(), f'Directory not exists: {PUBLIC_PATH}' LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django_example_ynh.log assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}' @@ -36,7 +36,7 @@ PATH_URL = PATH_URL.strip('/') # Function that will be called to finalize a user profile: YNH_SETUP_USER = 'setup_user.setup_project_user' -SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt +SECRET_KEY = __get_or_create_secret(FINALPATH / 'secret.txt') # /opt/yunohost/$app/secret.txt # INSTALLED_APPS.append('') @@ -50,8 +50,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 @@ -106,9 +106,8 @@ else: STATIC_URL = '/static/' MEDIA_URL = '/media/' -STATIC_ROOT = str(FINAL_WWW_PATH / 'static') -MEDIA_ROOT = str(FINAL_WWW_PATH / 'media') - +STATIC_ROOT = str(PUBLIC_PATH / 'static') +MEDIA_ROOT = str(PUBLIC_PATH / 'media') # ----------------------------------------------------------------------------- @@ -139,8 +138,16 @@ LOGGING = { '': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'django': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, 'axes': {'handlers': ['log_file', 'mail_admins'], 'level': 'WARNING', 'propagate': False}, - 'django_tools': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, - 'django_yunohost_integration': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False}, + 'django_tools': { + 'handlers': ['log_file', 'mail_admins'], + 'level': 'INFO', + 'propagate': False, + }, + 'django_yunohost_integration': { + 'handlers': ['log_file', 'mail_admins'], + 'level': 'INFO', + 'propagate': False, + }, }, } diff --git a/conf/django_example_ynh.service b/conf/systemd.service similarity index 100% rename from conf/django_example_ynh.service rename to conf/systemd.service diff --git a/conf/urls.py b/conf/urls.py index 2f0ddcd..e76b15e 100644 --- a/conf/urls.py +++ b/conf/urls.py @@ -1,3 +1,19 @@ +""" + urls.py + ~~~~~~~ + + Note: This is not a good example how your urls.py can look like. + Because this setup is just an example without a real Python application. + + Look at real examples, here: + + * https://github.com/YunoHost-Apps/django-fritzconnection_ynh/blob/master/conf/urls.py + * https://github.com/YunoHost-Apps/django-for-runners_ynh/blob/testing/conf/urls.py + * https://github.com/YunoHost-Apps/pyinventory_ynh/blob/testing/conf/urls.py + +""" + + from django.conf import settings from django.contrib import admin from django.urls import path @@ -5,9 +21,16 @@ from django.urls import path from django_yunohost_integration.views import request_media_debug_view -# settings.PATH_URL is the $YNH_APP_ARG_PATH -# Prefix all urls with "PATH_URL": -urlpatterns = [ - path(f'{settings.PATH_URL}/', admin.site.urls), - path(f'{settings.PATH_URL}/debug/', 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}/', admin.site.urls), + path(f'{settings.PATH_URL}/debug/', request_media_debug_view), + ] +else: + # Installed to domain root, without a path prefix + urlpatterns = [ + path('/', admin.site.urls), + path('/debug/', request_media_debug_view), + ] diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..37bc282 --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1,9 @@ +[![pytest](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django_example_ynh/actions/workflows/package_linter.yml) + +Demo [YunoHost Application](https://install-app.yunohost.org/?app=django_example_ynh) to demonstrate the integration of a Django project under YunoHost. + +[![Integration level](https://dash.yunohost.org/integration/django_example_ynh.svg)](https://dash.yunohost.org/appci/app/django_example_ynh) ![](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django_example_ynh.maintain.svg) +[![Install django_example_ynh with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django_example_ynh) + + +Pull requests welcome ;) diff --git a/doc/DISCLAIMER.md b/doc/DISCLAIMER.md new file mode 100644 index 0000000..f6b962b --- /dev/null +++ b/doc/DISCLAIMER.md @@ -0,0 +1,148 @@ +## local test + +For quicker developing of django_example_ynh 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_example_ynh.git +~$ cd django_example_ynh/ +~/django_example_ynh$ make +install-poetry install or update poetry +install install project via poetry +update update the sources and installation and generate "conf/requirements.txt" +lint Run code formatters and linter +fix-code-style Fix code formatting +tox-listenvs List all tox test environments +tox Run pytest via tox with all environments +pytest Run pytest +publish Release new version to PyPi +local-test Run local_test.py to run the project locally +local-diff-settings Run "manage.py diffsettings" with local test + +~/django_example_ynh$ make install-poetry +~/django_example_ynh$ make install +~/django_example_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/` + + +## history + +* [compare v0.1.5...master](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.2.0...master) **dev** + * tbc +* [v0.2.0 - 15.09.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.5...v0.2.0) + * rename/split `django_example_ynh` into: + * [django_yunohost_integration](https://github.com/jedie/django_yunohost_integration) - Python package with the glue code to integrate a Django project with YunoHost + * [django_example_ynh](https://github.com/YunoHost-Apps/django_example_ynh) - Demo YunoHost App to demonstrate the integration of a Django project under YunoHost +* [v0.1.5 - 19.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.4...v0.1.5) + * Make some deps `gunicorn`, `psycopg2-binary`, `django-redis`, `django-axes` optional +* [v0.1.4 - 08.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.3...v0.1.4) + * Bugfix [CSRF verification failed on POST requests #7](https://github.com/YunoHost-Apps/django_example_ynh/issues/7) +* [v0.1.3 - 08.01.2021](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.2...v0.1.3) + * set "DEBUG = True" in local_test (so static files are served and auth works) + * Bugfixes and cleanups +* [v0.1.2 - 29.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.1...v0.1.2) + * Bugfixes +* [v0.1.1 - 29.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/v0.1.0...v0.1.1) + * Refactor "create_superuser" to a manage command, useable via "django_example_ynh" in `INSTALLED_APPS` + * Generate "conf/requirements.txt" and use this file for install + * rename own settings and urls (in `/conf/`) +* [v0.1.0 - 28.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/compare/f578f14...v0.1.0) + * first working state +* [23.12.2020](https://github.com/YunoHost-Apps/django_example_ynh/commit/f578f144a3a6d11d7044597c37d550d29c247773) + * init the project + + +## Links + +* Report a bug about this package: https://github.com/YunoHost-Apps/django_example_ynh +* YunoHost website: https://yunohost.org/ +* PyPi package: https://pypi.org/project/django-ynh/ + +These projects used `django_example_ynh`: + +* https://github.com/YunoHost-Apps/django_example_ynh +* https://github.com/YunoHost-Apps/django-for-runners_ynh + +--- + +# Developer info + +The App project will be stored under `__FINALPATH__` (e.g.: `/opt/yunohost/$app`) that's Django's `settings.FINALPATH` +"static" / "media" files to serve via nginx are under `__PUBLIC_PATH__` (e.g.: `/var/www/$app`) that's `settings.PUBLIC_PATH` + +## package installation / debugging + +This app is not in YunoHost app catalog. Test install, e.g.: +```bash +~# git clone https://github.com/YunoHost-Apps/django_example_ynh.git +~# yunohost app install django_example_ynh/ -f +``` +To update: +```bash +~# cd django_example_ynh +~/django_example_ynh# git fetch && git reset --hard origin/testing +~/django_example_ynh# yunohost app upgrade django_example_ynh -u . -F +``` + +To remove call e.g.: +```bash +sudo yunohost app remove django_example_ynh +``` + +Backup / remove / restore cycle, e.g.: +```bash +yunohost backup create --apps django_example_ynh +yunohost backup list +archives: + - django_example_ynh-pre-upgrade1 + - 20201223-163434 +yunohost app remove django_example_ynh +yunohost backup restore 20201223-163434 --apps django_example_ynh +``` + +Debug the installation, e.g.: +```bash +root@yunohost:~# ls -la /var/www/django_example_ynh/ +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_example_ynh/ +total 58 +drwxr-xr-x 5 django_example_ynh django_example_ynh 11 Dec 8 08:39 . +drwxr-xr-x 3 root root 3 Dec 8 08:36 .. +-rw-r--r-- 1 django_example_ynh django_example_ynh 460 Dec 8 08:39 gunicorn.conf.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 0 Dec 8 08:39 local_settings.py +-rwxr-xr-x 1 django_example_ynh django_example_ynh 274 Dec 8 08:39 manage.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 171 Dec 8 08:39 secret.txt +drwxr-xr-x 6 django_example_ynh django_example_ynh 6 Dec 8 08:37 venv +-rw-r--r-- 1 django_example_ynh django_example_ynh 115 Dec 8 08:39 wsgi.py +-rw-r--r-- 1 django_example_ynh django_example_ynh 4737 Dec 8 08:39 django_example_ynh_demo_settings.py + +root@yunohost:~# cd /opt/yunohost/django_example_ynh/ +root@yunohost:/opt/yunohost/django_example_ynh# source venv/bin/activate +(venv) root@yunohost:/opt/yunohost/django_example_ynh# ./manage.py check +django_example_ynh v0.8.2 (Django v2.2.17) +DJANGO_SETTINGS_MODULE='django_example_ynh_demo_settings' +PROJECT_PATH:/opt/yunohost/django_example_ynh/venv/lib/python3.7/site-packages +BASE_PATH:/opt/yunohost/django_example_ynh +System check identified no issues (0 silenced). + +root@yunohost:~# tail -f /var/log/django_example_ynh/django_example_ynh.log +root@yunohost:~# cat /etc/systemd/system/systemd.service + +root@yunohost:~# systemctl reload-or-restart django_example_ynh +root@yunohost:~# journalctl --unit=django_example_ynh --follow +``` + + diff --git a/doc/screenshots/.gitkeep b/doc/screenshots/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/manifest.json b/manifest.json index 9cedf0e..5d1b7cd 100644 --- a/manifest.json +++ b/manifest.json @@ -3,10 +3,17 @@ "id": "django_example_ynh", "packaging_format": 1, "description": { - "en": "Demo YunoHost Application to demonstrate the integration of a Django project under YunoHost." + "en": "Demo YunoHost Application to demonstrate the integration of a Django project under YunoHost via https://github.com/YunoHost-Apps/django_yunohost_integration" }, - "version": "v0.2.0.alpha0~ynh1", + "version": "0.3.0~ynh1", "url": "https://github.com/YunoHost-Apps/django_example_ynh", + "upstream": { + "license": "GPL-3.0", + "website": "https://github.com/YunoHost-Apps/django_example_ynh", + "admindoc": "https://github.com/YunoHost-Apps/django_example_ynh", + "userdoc": "https://github.com/YunoHost-Apps/django_example_ynh", + "code": "https://github.com/YunoHost-Apps/django_example_ynh" + }, "license": "GPL-3.0", "maintainer": { "name": "Jens Diemer", @@ -14,49 +21,31 @@ }, "previous_maintainers": [], "requirements": { - "yunohost": ">= 4.0" + "yunohost": ">= 4.3" }, "multi_instance": true, "services": [ - "nginx" + "nginx", "postgresql", "redis" ], "arguments": { "install" : [ { "name": "domain", - "type": "domain", - "ask": { - "en": "Choose a domain for PyInventory", - "fr": "Choisissez un domaine pour PyInventory" - }, - "example": "domain.org" + "type": "domain" }, { "name": "path", "type": "path", - "ask": { - "en": "Choose a path for PyInventory", - "fr": "Choisissez un chemin pour PyInventory" - }, "example": "/django_example_ynh", "default": "/django_example_ynh" }, { "name": "admin", - "type": "user", - "ask": { - "en": "Choose an admin user for PyInventory", - "fr": "Choisissez l'administrateur pour PyInventory" - }, - "example": "johndoe" + "type": "user" }, { "name": "is_public", "type": "boolean", - "ask": { - "en": "Should PyInventory be public accessible?", - "fr": "PyInventory doit-il être accessible au public ?" - }, "help": { "en": "Any YunoHost user and anonymous people from the web will be able to access the application", "fr": "Tout utilisateur YunoHost et les personnes anonymes pourront accéder à l'application" diff --git a/poetry.lock b/poetry.lock index a47246a..9ab0cd4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,28 +1,31 @@ [[package]] name = "asgiref" -version = "3.4.1" +version = "3.5.2" description = "ASGI specs, helper code, and adapters" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] +tests = ["mypy (>=0.800)", "pytest-asyncio", "pytest"] [[package]] -name = "astor" -version = "0.8.1" -description = "Read/rewrite/write Python ASTs" -category = "dev" +name = "async-timeout" +version = "4.0.2" +description = "Timeout context manager for asyncio programs" +category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = ">=3.6" + +[package.dependencies] +typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} [[package]] name = "atomicwrites" -version = "1.4.0" +version = "1.4.1" description = "Atomic file writes." category = "dev" optional = false @@ -30,108 +33,88 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "21.2.0" +version = "22.1.0" description = "Classes Without Boilerplate" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] - -[[package]] -name = "backports.entry-points-selectable" -version = "1.1.0" -description = "Compatibility shim providing selectable entry points for older implementations" -category = "dev" -optional = false -python-versions = ">=2.7" - -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-flake8", "pytest-cov", "pytest-black (>=0.3.7)", "pytest-mypy", "pytest-checkdocs (>=2.4)", "pytest-enabler (>=1.0.1)"] +tests_no_zope = ["cloudpickle", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +tests = ["cloudpickle", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] +docs = ["sphinx-notfound-page", "zope.interface", "sphinx", "furo"] +dev = ["cloudpickle", "pre-commit", "sphinx-notfound-page", "sphinx", "furo", "zope.interface", "pytest-mypy-plugins", "mypy (>=0.900,!=0.940)", "pytest (>=4.3.0)", "pympler", "hypothesis", "coverage[toml] (>=5.0.2)"] [[package]] name = "black" -version = "21.9b0" +version = "22.6.0" description = "The uncompromising code formatter." category = "dev" optional = false python-versions = ">=3.6.2" [package.dependencies] -click = ">=7.1.2" +click = ">=8.0.0" mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0,<1" +pathspec = ">=0.9.0" platformdirs = ">=2" -regex = ">=2020.1.8" -tomli = ">=0.2.6,<2.0.0" -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\""} -typing-extensions = [ - {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, - {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, -] +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.6.0)", "aiohttp-cors (>=0.4.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -python2 = ["typed-ast (>=1.4.2)"] uvloop = ["uvloop (>=0.15.2)"] +jupyter = ["tokenize-rt (>=3.2.0)", "ipython (>=7.8.0)"] +d = ["aiohttp (>=3.7.4)"] +colorama = ["colorama (>=0.4.3)"] [[package]] name = "bx-django-utils" -version = "5" +version = "26" description = "Various Django utility functions" category = "dev" optional = false -python-versions = ">=3.6,<4.0.0" +python-versions = ">=3.7,<4.0.0" [package.dependencies] -bx_py_utils = ">=41" +bx_py_utils = ">=52" django = "*" python-stdnum = "*" [[package]] name = "bx-py-utils" -version = "44" +version = "67" description = "Various Python utility functions" category = "dev" optional = false -python-versions = ">=3.6,<4.0.0" +python-versions = ">=3.7,<4.0.0" [[package]] name = "certifi" -version = "2021.5.30" +version = "2022.6.15" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "charset-normalizer" -version = "2.0.5" +version = "2.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "dev" optional = false -python-versions = ">=3.5.0" +python-versions = ">=3.6.0" [package.extras] unicode_backport = ["unicodedata2"] [[package]] name = "click" -version = "8.0.1" +version = "8.1.3" description = "Composable command line interface toolkit" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -139,7 +122,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "dev" optional = false @@ -147,34 +130,70 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "coverage" -version = "5.5" +version = "6.4.3" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +python-versions = ">=3.7" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} [package.extras] -toml = ["toml"] +toml = ["tomli"] [[package]] name = "coveralls" -version = "3.2.0" +version = "3.3.1" description = "Show coverage stats online via coveralls.io" category = "dev" optional = false python-versions = ">= 3.5" [package.dependencies] -coverage = ">=4.1,<6.0" +coverage = ">=4.1,<6.0.0 || >6.1,<6.1.1 || >6.1.1,<7.0" docopt = ">=0.6.1" requests = ">=1.0.0" [package.extras] yaml = ["PyYAML (>=3.10)"] +[[package]] +name = "darker" +version = "1.5.0" +description = "Apply Black formatting only in regions changed since last commit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +black = ">=21.5b1" +toml = ">=0.10.0" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +test = ["wheel (>=0.21.0)", "types-toml (>=0.10.4)", "types-requests (>=2.27.9)", "twine (>=2.0.0)", "safety (>=1.10.3)", "ruamel.yaml (>=0.17.21)", "requests-cache (>=0.7)", "regex (>=2021.4.4)", "pyupgrade (>=2.31.0)", "pytest-mypy", "pytest-kwparametrize (>=0.0.3)", "pytest-isort (>=1.1.0)", "pytest-flake8 (>=1.0.6)", "pytest-darker", "pytest (>=6.2.0)", "pylint", "pygments", "mypy (>=0.940)", "flake8-comprehensions (>=3.7.0)", "flake8-bugbear (>=22.1.11)", "flake8-2020 (>=1.6.1)", "flake8 (<4)", "defusedxml (>=0.7.1)", "codespell (>=2.1.0)", "black (>=21.7b1)", "bandit (>=1.7.1)", "airium (>=0.2.3)"] +release = ["requests-cache (>=0.7)", "defusedxml (>=0.7.1)", "click (>=8.0.0)", "airium (>=0.2.3)"] +isort = ["isort (>=5.0.1)"] +color = ["Pygments (>=2.4.0)"] + +[[package]] +name = "deprecated" +version = "1.2.13" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["pytest-cov", "pytest", "PyTest-Cov (<2.6)", "PyTest (<5)", "zipp (<2)", "sphinxcontrib-websupport (<2)", "configparser (<5)", "importlib-resources (<4)", "importlib-metadata (<3)", "sphinx (<2)", "bump2version (<1)", "tox"] + [[package]] name = "distlib" -version = "0.3.2" +version = "0.3.5" description = "Distribution utilities" category = "dev" optional = false @@ -182,7 +201,7 @@ python-versions = "*" [[package]] name = "django" -version = "3.2.7" +version = "3.2.15" description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false @@ -194,24 +213,24 @@ pytz = "*" sqlparse = ">=0.2.2" [package.extras] -argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] +argon2 = ["argon2-cffi (>=19.1.0)"] [[package]] name = "django-axes" -version = "5.24.0" +version = "5.36.0" description = "Keep track of failed login attempts in Django-powered sites." category = "main" optional = false -python-versions = "~=3.6" +python-versions = ">=3.7" [package.dependencies] -django = ">=2.2" -django-ipware = ">=3,<5" +django = ">=3.2" +django-ipware = ">=3" [[package]] name = "django-ipware" -version = "4.0.0" +version = "4.0.2" description = "A Django application to retrieve user's IP address" category = "main" optional = false @@ -219,7 +238,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "django-redis" -version = "5.0.0" +version = "5.2.0" description = "Full featured redis cache backend for Django." category = "main" optional = false @@ -227,11 +246,14 @@ python-versions = ">=3.6" [package.dependencies] Django = ">=2.2" -redis = ">=3.0.0" +redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1" + +[package.extras] +hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] [[package]] name = "django-yunohost-integration" -version = "0.2.0" +version = "0.2.5" description = "Glue code to package django projects as yunohost apps." category = "main" optional = false @@ -245,7 +267,7 @@ gunicorn = {version = "*", optional = true, markers = "extra == \"ynh\""} psycopg2 = {version = "*", optional = true, markers = "extra == \"ynh\""} [package.extras] -ynh = ["django-axes", "django-redis", "gunicorn", "psycopg2"] +ynh = ["psycopg2", "gunicorn", "django-redis", "django-axes"] [[package]] name = "docopt" @@ -257,36 +279,29 @@ python-versions = "*" [[package]] name = "filelock" -version = "3.0.12" +version = "3.8.0" description = "A platform independent file lock." category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" + +[package.extras] +testing = ["pytest-timeout (>=2.1)", "pytest-cov (>=3)", "pytest (>=7.1.2)", "coverage (>=6.4.2)", "covdefaults (>=2.2)"] +docs = ["sphinx-autodoc-typehints (>=1.19.1)", "sphinx (>=5.1.1)", "furo (>=2022.6.21)"] [[package]] name = "flake8" -version = "3.9.2" +version = "5.0.4" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6.1" [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" - -[[package]] -name = "flynt" -version = "0.69" -description = "CLI tool to convert a python project's %-formatted strings to f-strings." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -astor = "*" +importlib-metadata = {version = ">=1.1.0,<4.3", markers = "python_version < \"3.8\""} +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.9.0,<2.10.0" +pyflakes = ">=2.5.0,<2.6.0" [[package]] name = "gunicorn" @@ -304,7 +319,7 @@ tornado = ["tornado (>=0.2)"] [[package]] name = "idna" -version = "3.2" +version = "3.3" description = "Internationalized Domain Names in Applications (IDNA)" category = "dev" optional = false @@ -312,9 +327,9 @@ python-versions = ">=3.5" [[package]] name = "importlib-metadata" -version = "4.8.1" +version = "4.2.0" description = "Read metadata from Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -323,9 +338,8 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -perf = ["ipython"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] +testing = ["importlib-resources (>=1.3)", "pytest-mypy", "pytest-black (>=0.3.7)", "flufl.flake8", "pyfakefs", "pep517", "packaging", "pytest-enabler (>=1.0.1)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=4.6)"] +docs = ["rst.linker (>=1.9)", "jaraco.packaging (>=8.2)", "sphinx"] [[package]] name = "iniconfig" @@ -337,25 +351,25 @@ python-versions = "*" [[package]] name = "isort" -version = "5.9.3" +version = "5.10.1" description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.6.1,<4.0" [package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] -colors = ["colorama (>=0.4.3,<0.5.0)"] plugins = ["setuptools"] +colors = ["colorama (>=0.4.3,<0.5.0)"] +requirements_deprecated_finder = ["pip-api", "pipreqs"] +pipfile_deprecated_finder = ["requirementslib", "pipreqs"] [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "mypy-extensions" @@ -367,14 +381,14 @@ python-versions = "*" [[package]] name = "packaging" -version = "21.0" +version = "21.3" description = "Core utilities for Python packages" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -pyparsing = ">=2.0.2" +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pathspec" @@ -386,15 +400,15 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "platformdirs" -version = "2.3.0" +version = "2.5.2" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +test = ["pytest (>=6)", "pytest-mock (>=3.6)", "pytest-cov (>=2.7)", "appdirs (==1.4.4)"] +docs = ["sphinx (>=4)", "sphinx-autodoc-typehints (>=1.12)", "proselint (>=0.10.2)", "furo (>=2021.7.5b38)"] [[package]] name = "pluggy" @@ -408,12 +422,12 @@ python-versions = ">=3.6" importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] +testing = ["pytest-benchmark", "pytest"] +dev = ["tox", "pre-commit"] [[package]] name = "psycopg2" -version = "2.9.1" +version = "2.9.3" description = "psycopg2 - Python-PostgreSQL Database Adapter" category = "main" optional = false @@ -421,43 +435,46 @@ python-versions = ">=3.6" [[package]] name = "py" -version = "1.10.0" +version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pycodestyle" -version = "2.7.0" +version = "2.9.1" description = "Python style guide checker" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "pyflakes" -version = "2.3.1" +version = "2.5.0" description = "passive checker of Python programs" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "pyparsing" -version = "2.4.7" -description = "Python parsing module" -category = "dev" +version = "3.0.9" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.6.8" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "6.2.5" +version = "7.1.2" description = "pytest: simple powerful testing with Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} @@ -468,30 +485,44 @@ iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" py = ">=1.8.2" -toml = "*" +tomli = ">=1.0.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["xmlschema", "requests", "pygments (>=2.7.2)", "nose", "mock", "hypothesis (>=3.56)", "argcomplete"] [[package]] name = "pytest-cov" -version = "2.12.1" +version = "3.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=5.2.1" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" -toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] +testing = ["virtualenv", "pytest-xdist", "six", "process-tests", "hunter", "fields"] + +[[package]] +name = "pytest-darker" +version = "0.1.2" +description = "A pytest plugin for checking of modified code using Darker" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +darker = ">=1.1.0" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} + +[package.extras] +test = ["pytest-mypy", "pytest-isort (>=1.1.0)", "pytest-black", "pytest (>=6.0.1)", "mypy (>=0.782)"] [[package]] name = "pytest-django" -version = "4.4.0" +version = "4.5.2" description = "A Django plugin for pytest." category = "dev" optional = false @@ -501,77 +532,66 @@ python-versions = ">=3.5" pytest = ">=5.4.0" [package.extras] -docs = ["sphinx", "sphinx-rtd-theme"] -testing = ["django", "django-configurations (>=2.0)"] +testing = ["django-configurations (>=2.0)", "django"] +docs = ["sphinx-rtd-theme", "sphinx"] [[package]] name = "python-stdnum" -version = "1.16" +version = "1.17" description = "Python module to handle standardized numbers and codes" category = "dev" optional = false python-versions = "*" [package.extras] -soap = ["zeep"] -soap-alt = ["suds"] soap-fallback = ["pysimplesoap"] +soap-alt = ["suds"] +soap = ["zeep"] [[package]] name = "pytz" -version = "2021.1" +version = "2022.2.1" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" -[[package]] -name = "pyupgrade" -version = "2.26.0" -description = "A tool to automatically upgrade syntax for newer versions." -category = "dev" -optional = false -python-versions = ">=3.6.1" - -[package.dependencies] -tokenize-rt = ">=3.2.0" - [[package]] name = "redis" -version = "3.5.3" -description = "Python client for Redis key-value store" +version = "4.3.4" +description = "Python client for Redis database and key-value store" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" + +[package.dependencies] +async-timeout = ">=4.0.2" +deprecated = ">=1.2.3" +importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} +packaging = ">=20.4" +typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] -hiredis = ["hiredis (>=0.1.3)"] - -[[package]] -name = "regex" -version = "2021.8.28" -description = "Alternative regular expression module, to replace re." -category = "dev" -optional = false -python-versions = "*" +ocsp = ["requests (>=2.26.0)", "pyopenssl (==20.0.1)", "cryptography (>=36.0.1)"] +hiredis = ["hiredis (>=1.0.0)"] [[package]] name = "requests" -version = "2.26.0" +version = "2.28.1" description = "Python HTTP for Humans." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] [[package]] name = "six" @@ -589,14 +609,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "tokenize-rt" -version = "4.1.0" -description = "A wrapper around the stdlib `tokenize` which roundtrips." -category = "dev" -optional = false -python-versions = ">=3.6.1" - [[package]] name = "toml" version = "0.10.2" @@ -607,15 +619,15 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "tomli" -version = "1.2.1" +version = "2.0.1" description = "A lil' TOML parser" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "tox" -version = "3.24.3" +version = "3.25.1" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false @@ -633,365 +645,340 @@ toml = ">=0.9.4" virtualenv = ">=16.0.0,<20.0.0 || >20.0.0,<20.0.1 || >20.0.1,<20.0.2 || >20.0.2,<20.0.3 || >20.0.3,<20.0.4 || >20.0.4,<20.0.5 || >20.0.5,<20.0.6 || >20.0.6,<20.0.7 || >20.0.7" [package.extras] -docs = ["pygments-github-lexers (>=0.0.5)", "sphinx (>=2.0.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "towncrier (>=18.5.0)"] -testing = ["flaky (>=3.4.0)", "freezegun (>=0.3.11)", "psutil (>=5.6.1)", "pytest (>=4.0.0)", "pytest-cov (>=2.5.1)", "pytest-mock (>=1.10.0)", "pytest-randomly (>=1.0.0)", "pytest-xdist (>=1.22.2)", "pathlib2 (>=2.3.3)"] +testing = ["pathlib2 (>=2.3.3)", "psutil (>=5.6.1)", "pytest-randomly (>=1.0.0)", "pytest-mock (>=1.10.0)", "pytest-cov (>=2.5.1)", "pytest (>=4.0.0)", "freezegun (>=0.3.11)", "flaky (>=3.4.0)"] +docs = ["towncrier (>=18.5.0)", "sphinxcontrib-autoprogram (>=0.1.5)", "sphinx (>=2.0.0)", "pygments-github-lexers (>=0.0.5)"] [[package]] name = "typed-ast" -version = "1.4.3" +version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false -python-versions = "*" - -[[package]] -name = "typing-extensions" -version = "3.10.0.2" -description = "Backported and Experimental Type Hints for Python 3.5+" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "urllib3" -version = "1.26.6" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" - -[package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "virtualenv" -version = "20.7.2" -description = "Virtual Python Environment builder" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[package.dependencies] -"backports.entry-points-selectable" = ">=1.0.4" -distlib = ">=0.3.1,<1" -filelock = ">=3.0.0,<4" -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -platformdirs = ">=2,<3" -six = ">=1.9.0,<2" - -[package.extras] -docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] -testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] - -[[package]] -name = "zipp" -version = "3.5.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false python-versions = ">=3.6" +[[package]] +name = "typing-extensions" +version = "4.3.0" +description = "Backported and Experimental Type Hints for Python 3.7+" +category = "main" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "urllib3" +version = "1.26.11" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4" + [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +secure = ["ipaddress", "certifi", "idna (>=2.0.0)", "cryptography (>=1.3.4)", "pyOpenSSL (>=0.14)"] +brotli = ["brotlipy (>=0.6.0)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] + +[[package]] +name = "virtualenv" +version = "20.16.2" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +distlib = ">=0.3.1,<1" +filelock = ">=3.2,<4" +importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +platformdirs = ">=2,<3" + +[package.extras] +testing = ["pytest-timeout (>=1)", "pytest-randomly (>=1)", "pytest-mock (>=2)", "pytest-freezegun (>=0.4.1)", "pytest-env (>=0.6.2)", "pytest (>=4)", "packaging (>=20.0)", "flaky (>=3)", "coverage-enable-subprocess (>=1)", "coverage (>=4)"] +docs = ["towncrier (>=21.3)", "sphinx-rtd-theme (>=0.4.3)", "sphinx-argparse (>=0.2.5)", "sphinx (>=3)", "proselint (>=0.10.2)"] + +[[package]] +name = "wrapt" +version = "1.14.1" +description = "Module for decorators, wrappers and monkey patching." +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "zipp" +version = "3.8.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +testing = ["pytest-mypy (>=0.9.1)", "pytest-black (>=0.3.7)", "func-timeout", "jaraco.itertools", "pytest-enabler (>=1.3)", "pytest-cov", "pytest-flake8", "pytest-checkdocs (>=2.4)", "pytest (>=6)"] +docs = ["jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "jaraco.packaging (>=9)", "sphinx"] [metadata] lock-version = "1.1" -python-versions = ">=3.7,<4.0.0" -content-hash = "7cd6494e5cfb25528c3c64bd933cf65aa468e9e0c12dc5fb70a01a0f3ec4eabf" +python-versions = ">=3.7,<4.0.0" # TODO: Update to >=3.8 after YunoHost updates to Bullseye +content-hash = "477d486f59495a9e626d97f184b0c05db2642a62627f98758cdb90221cea1ebf" [metadata.files] asgiref = [ - {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, - {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, + {file = "asgiref-3.5.2-py3-none-any.whl", hash = "sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4"}, + {file = "asgiref-3.5.2.tar.gz", hash = "sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424"}, ] -astor = [ - {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, - {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, +async-timeout = [ + {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, + {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, ] atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] attrs = [ - {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, - {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, -] -"backports.entry-points-selectable" = [ - {file = "backports.entry_points_selectable-1.1.0-py2.py3-none-any.whl", hash = "sha256:a6d9a871cde5e15b4c4a53e3d43ba890cc6861ec1332c9c2428c92f977192acc"}, - {file = "backports.entry_points_selectable-1.1.0.tar.gz", hash = "sha256:988468260ec1c196dab6ae1149260e2f5472c9110334e5d51adcb77867361f6a"}, + {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, + {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] black = [ - {file = "black-21.9b0-py3-none-any.whl", hash = "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115"}, - {file = "black-21.9b0.tar.gz", hash = "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91"}, + {file = "black-22.6.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f586c26118bc6e714ec58c09df0157fe2d9ee195c764f630eb0d8e7ccce72e69"}, + {file = "black-22.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b270a168d69edb8b7ed32c193ef10fd27844e5c60852039599f9184460ce0807"}, + {file = "black-22.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6797f58943fceb1c461fb572edbe828d811e719c24e03375fd25170ada53825e"}, + {file = "black-22.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c85928b9d5f83b23cee7d0efcb310172412fbf7cb9d9ce963bd67fd141781def"}, + {file = "black-22.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6fe02afde060bbeef044af7996f335fbe90b039ccf3f5eb8f16df8b20f77666"}, + {file = "black-22.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cfaf3895a9634e882bf9d2363fed5af8888802d670f58b279b0bece00e9a872d"}, + {file = "black-22.6.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94783f636bca89f11eb5d50437e8e17fbc6a929a628d82304c80fa9cd945f256"}, + {file = "black-22.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2ea29072e954a4d55a2ff58971b83365eba5d3d357352a07a7a4df0d95f51c78"}, + {file = "black-22.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e439798f819d49ba1c0bd9664427a05aab79bfba777a6db94fd4e56fae0cb849"}, + {file = "black-22.6.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:187d96c5e713f441a5829e77120c269b6514418f4513a390b0499b0987f2ff1c"}, + {file = "black-22.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:074458dc2f6e0d3dab7928d4417bb6957bb834434516f21514138437accdbe90"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a218d7e5856f91d20f04e931b6f16d15356db1c846ee55f01bac297a705ca24f"}, + {file = "black-22.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:568ac3c465b1c8b34b61cd7a4e349e93f91abf0f9371eda1cf87194663ab684e"}, + {file = "black-22.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6c1734ab264b8f7929cef8ae5f900b85d579e6cbfde09d7387da8f04771b51c6"}, + {file = "black-22.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9a3ac16efe9ec7d7381ddebcc022119794872abce99475345c5a61aa18c45ad"}, + {file = "black-22.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:b9fd45787ba8aa3f5e0a0a98920c1012c884622c6c920dbe98dbd05bc7c70fbf"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ba9be198ecca5031cd78745780d65a3f75a34b2ff9be5837045dce55db83d1c"}, + {file = "black-22.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3db5b6409b96d9bd543323b23ef32a1a2b06416d525d27e0f67e74f1446c8f2"}, + {file = "black-22.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:560558527e52ce8afba936fcce93a7411ab40c7d5fe8c2463e279e843c0328ee"}, + {file = "black-22.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b154e6bbde1e79ea3260c4b40c0b7b3109ffcdf7bc4ebf8859169a6af72cd70b"}, + {file = "black-22.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:4af5bc0e1f96be5ae9bd7aaec219c901a94d6caa2484c21983d043371c733fc4"}, + {file = "black-22.6.0-py3-none-any.whl", hash = "sha256:ac609cf8ef5e7115ddd07d85d988d074ed00e10fbc3445aee393e70164a2219c"}, + {file = "black-22.6.0.tar.gz", hash = "sha256:6c6d39e28aed379aec40da1c65434c77d75e65bb59a1e1c283de545fb4e7c6c9"}, ] bx-django-utils = [ - {file = "bx_django_utils-5-py3-none-any.whl", hash = "sha256:5297ef03dd03539237c67d3faea8490acdba643629637afbab9603e2ceefa04c"}, - {file = "bx_django_utils-5.tar.gz", hash = "sha256:30800d46b3836c99215f609323b1cd41f26727cb1037fe47bbf55fcb36789998"}, + {file = "bx_django_utils-26-py3-none-any.whl", hash = "sha256:c04776c4c6b275ddcadae79fd1578e6ae9ba92d8cf752a9ee4f2b70a22f4236e"}, + {file = "bx_django_utils-26.tar.gz", hash = "sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1"}, ] bx-py-utils = [ - {file = "bx_py_utils-44-py3-none-any.whl", hash = "sha256:d253c0daf32682201a03e4f80a90028ebdfbad7a93b102a7befcf003a1624a4d"}, - {file = "bx_py_utils-44.tar.gz", hash = "sha256:693daa83e5037db527b0e7254de4bacc6c05f1c0153714eacfa7d366d58709e8"}, + {file = "bx_py_utils-67-py3-none-any.whl", hash = "sha256:4810dcab69146ffd5c31d45710c47fa9ac63f074b26326bc2f17eb7eb7f5e09e"}, + {file = "bx_py_utils-67.tar.gz", hash = "sha256:981877273d1c480f8d6f1de78b1a034c97b5e420df75e66799b320ff9133a047"}, ] certifi = [ - {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, - {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.0.5.tar.gz", hash = "sha256:7098e7e862f6370a2a8d1a6398cd359815c45d12626267652c3f13dec58e2367"}, - {file = "charset_normalizer-2.0.5-py3-none-any.whl", hash = "sha256:fa471a601dfea0f492e4f4fca035cd82155e65dc45c9b83bf4322dfab63755dd"}, + {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, + {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, ] click = [ - {file = "click-8.0.1-py3-none-any.whl", hash = "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"}, - {file = "click-8.0.1.tar.gz", hash = "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a"}, + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] coverage = [ - {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:b7895207b4c843c76a25ab8c1e866261bcfe27bfaa20c192de5190121770672b"}, - {file = "coverage-5.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:c2723d347ab06e7ddad1a58b2a821218239249a9e4365eaff6649d31180c1669"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:900fbf7759501bc7807fd6638c947d7a831fc9fdf742dc10f02956ff7220fa90"}, - {file = "coverage-5.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:004d1880bed2d97151facef49f08e255a20ceb6f9432df75f4eef018fdd5a78c"}, - {file = "coverage-5.5-cp27-cp27m-win32.whl", hash = "sha256:06191eb60f8d8a5bc046f3799f8a07a2d7aefb9504b0209aff0b47298333302a"}, - {file = "coverage-5.5-cp27-cp27m-win_amd64.whl", hash = "sha256:7501140f755b725495941b43347ba8a2777407fc7f250d4f5a7d2a1050ba8e82"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:372da284cfd642d8e08ef606917846fa2ee350f64994bebfbd3afb0040436905"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:8963a499849a1fc54b35b1c9f162f4108017b2e6db2c46c1bed93a72262ed083"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:869a64f53488f40fa5b5b9dcb9e9b2962a66a87dab37790f3fcfb5144b996ef5"}, - {file = "coverage-5.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4a7697d8cb0f27399b0e393c0b90f0f1e40c82023ea4d45d22bce7032a5d7b81"}, - {file = "coverage-5.5-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8d0a0725ad7c1a0bcd8d1b437e191107d457e2ec1084b9f190630a4fb1af78e6"}, - {file = "coverage-5.5-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:51cb9476a3987c8967ebab3f0fe144819781fca264f57f89760037a2ea191cb0"}, - {file = "coverage-5.5-cp310-cp310-win_amd64.whl", hash = "sha256:c0891a6a97b09c1f3e073a890514d5012eb256845c451bd48f7968ef939bf4ae"}, - {file = "coverage-5.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:3487286bc29a5aa4b93a072e9592f22254291ce96a9fbc5251f566b6b7343cdb"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:deee1077aae10d8fa88cb02c845cfba9b62c55e1183f52f6ae6a2df6a2187160"}, - {file = "coverage-5.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f11642dddbb0253cc8853254301b51390ba0081750a8ac03f20ea8103f0c56b6"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:6c90e11318f0d3c436a42409f2749ee1a115cd8b067d7f14c148f1ce5574d701"}, - {file = "coverage-5.5-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:30c77c1dc9f253283e34c27935fded5015f7d1abe83bc7821680ac444eaf7793"}, - {file = "coverage-5.5-cp35-cp35m-win32.whl", hash = "sha256:9a1ef3b66e38ef8618ce5fdc7bea3d9f45f3624e2a66295eea5e57966c85909e"}, - {file = "coverage-5.5-cp35-cp35m-win_amd64.whl", hash = "sha256:972c85d205b51e30e59525694670de6a8a89691186012535f9d7dbaa230e42c3"}, - {file = "coverage-5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:af0e781009aaf59e25c5a678122391cb0f345ac0ec272c7961dc5455e1c40066"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:74d881fc777ebb11c63736622b60cb9e4aee5cace591ce274fb69e582a12a61a"}, - {file = "coverage-5.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:92b017ce34b68a7d67bd6d117e6d443a9bf63a2ecf8567bb3d8c6c7bc5014465"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d636598c8305e1f90b439dbf4f66437de4a5e3c31fdf47ad29542478c8508bbb"}, - {file = "coverage-5.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:41179b8a845742d1eb60449bdb2992196e211341818565abded11cfa90efb821"}, - {file = "coverage-5.5-cp36-cp36m-win32.whl", hash = "sha256:040af6c32813fa3eae5305d53f18875bedd079960822ef8ec067a66dd8afcd45"}, - {file = "coverage-5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:5fec2d43a2cc6965edc0bb9e83e1e4b557f76f843a77a2496cbe719583ce8184"}, - {file = "coverage-5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18ba8bbede96a2c3dde7b868de9dcbd55670690af0988713f0603f037848418a"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:2910f4d36a6a9b4214bb7038d537f015346f413a975d57ca6b43bf23d6563b53"}, - {file = "coverage-5.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:f0b278ce10936db1a37e6954e15a3730bea96a0997c26d7fee88e6c396c2086d"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:796c9c3c79747146ebd278dbe1e5c5c05dd6b10cc3bcb8389dfdf844f3ead638"}, - {file = "coverage-5.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:53194af30d5bad77fcba80e23a1441c71abfb3e01192034f8246e0d8f99528f3"}, - {file = "coverage-5.5-cp37-cp37m-win32.whl", hash = "sha256:184a47bbe0aa6400ed2d41d8e9ed868b8205046518c52464fde713ea06e3a74a"}, - {file = "coverage-5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:2949cad1c5208b8298d5686d5a85b66aae46d73eec2c3e08c817dd3513e5848a"}, - {file = "coverage-5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:217658ec7187497e3f3ebd901afdca1af062b42cfe3e0dafea4cced3983739f6"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1aa846f56c3d49205c952d8318e76ccc2ae23303351d9270ab220004c580cfe2"}, - {file = "coverage-5.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:24d4a7de75446be83244eabbff746d66b9240ae020ced65d060815fac3423759"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d1f8bf7b90ba55699b3a5e44930e93ff0189aa27186e96071fac7dd0d06a1873"}, - {file = "coverage-5.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:970284a88b99673ccb2e4e334cfb38a10aab7cd44f7457564d11898a74b62d0a"}, - {file = "coverage-5.5-cp38-cp38-win32.whl", hash = "sha256:01d84219b5cdbfc8122223b39a954820929497a1cb1422824bb86b07b74594b6"}, - {file = "coverage-5.5-cp38-cp38-win_amd64.whl", hash = "sha256:2e0d881ad471768bf6e6c2bf905d183543f10098e3b3640fc029509530091502"}, - {file = "coverage-5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d1f9ce122f83b2305592c11d64f181b87153fc2c2bbd3bb4a3dde8303cfb1a6b"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:13c4ee887eca0f4c5a247b75398d4114c37882658300e153113dafb1d76de529"}, - {file = "coverage-5.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52596d3d0e8bdf3af43db3e9ba8dcdaac724ba7b5ca3f6358529d56f7a166f8b"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2cafbbb3af0733db200c9b5f798d18953b1a304d3f86a938367de1567f4b5bff"}, - {file = "coverage-5.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:44d654437b8ddd9eee7d1eaee28b7219bec228520ff809af170488fd2fed3e2b"}, - {file = "coverage-5.5-cp39-cp39-win32.whl", hash = "sha256:d314ed732c25d29775e84a960c3c60808b682c08d86602ec2c3008e1202e3bb6"}, - {file = "coverage-5.5-cp39-cp39-win_amd64.whl", hash = "sha256:13034c4409db851670bc9acd836243aeee299949bd5673e11844befcb0149f03"}, - {file = "coverage-5.5-pp36-none-any.whl", hash = "sha256:f030f8873312a16414c0d8e1a1ddff2d3235655a2174e3648b4fa66b3f2f1079"}, - {file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"}, - {file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"}, + {file = "coverage-6.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f50d3a822947572496ea922ee7825becd8e3ae6fbd2400cd8236b7d64b17f285"}, + {file = "coverage-6.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d5191d53afbe5b6059895fa7f58223d3751c42b8101fb3ce767e1a0b1a1d8f87"}, + {file = "coverage-6.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04010af3c06ce2bfeb3b1e4e05d136f88d88c25f76cd4faff5d1fd84d11581ea"}, + {file = "coverage-6.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6630d8d943644ea62132789940ca97d05fac83f73186eaf0930ffa715fbdab6b"}, + {file = "coverage-6.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05de0762c1caed4a162b3e305f36cf20a548ff4da0be6766ad5c870704be3660"}, + {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e3a41aad5919613483aad9ebd53336905cab1bd6788afd3995c2a972d89d795"}, + {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a2738ba1ee544d6f294278cfb6de2dc1f9a737a780469b5366e662a218f806c3"}, + {file = "coverage-6.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a0d2df4227f645a879010461df2cea6b7e3fb5a97d7eafa210f7fb60345af9e8"}, + {file = "coverage-6.4.3-cp310-cp310-win32.whl", hash = "sha256:73a10939dc345460ca0655356a470dd3de9759919186a82383c87b6eb315faf2"}, + {file = "coverage-6.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:53c8edd3b83a4ddba3d8c506f1359401e7770b30f2188f15c17a338adf5a14db"}, + {file = "coverage-6.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1eda5cae434282712e40b42aaf590b773382afc3642786ac3ed39053973f61f"}, + {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59fc88bc13e30f25167e807b8cad3c41b7218ef4473a20c86fd98a7968733083"}, + {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75314b00825d70e1e34b07396e23f47ed1d4feedc0122748f9f6bd31a544840"}, + {file = "coverage-6.4.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52f8b9fcf3c5e427d51bbab1fb92b575a9a9235d516f175b24712bcd4b5be917"}, + {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5a559aab40c716de80c7212295d0dc96bc1b6c719371c20dd18c5187c3155518"}, + {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:306788fd019bb90e9cbb83d3f3c6becad1c048dd432af24f8320cf38ac085684"}, + {file = "coverage-6.4.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:920a734fe3d311ca01883b4a19aa386c97b82b69fbc023458899cff0a0d621b9"}, + {file = "coverage-6.4.3-cp37-cp37m-win32.whl", hash = "sha256:ab9ef0187d6c62b09dec83a84a3b94f71f9690784c84fd762fb3cf2d2b44c914"}, + {file = "coverage-6.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:39ebd8e120cb77a06ee3d5fc26f9732670d1c397d7cd3acf02f6f62693b89b80"}, + {file = "coverage-6.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc698580216050b5f4a34d2cdd2838b429c53314f1c4835fab7338200a8396f2"}, + {file = "coverage-6.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:877ee5478fd78e100362aed56db47ccc5f23f6e7bb035a8896855f4c3e49bc9b"}, + {file = "coverage-6.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:555a498999c44f5287cc95500486cd0d4f021af9162982cbe504d4cb388f73b5"}, + {file = "coverage-6.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eff095a5aac7011fdb51a2c82a8fae9ec5211577f4b764e1e59cfa27ceeb1b59"}, + {file = "coverage-6.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5de1e9335e2569974e20df0ce31493d315a830d7987e71a24a2a335a8d8459d3"}, + {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7856ea39059d75f822ff0df3a51ea6d76307c897048bdec3aad1377e4e9dca20"}, + {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:411fdd9f4203afd93b056c0868c8f9e5e16813e765de962f27e4e5798356a052"}, + {file = "coverage-6.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cdf7b83f04a313a21afb1f8730fe4dd09577fefc53bbdfececf78b2006f4268e"}, + {file = "coverage-6.4.3-cp38-cp38-win32.whl", hash = "sha256:ab2b1a89d2bc7647622e9eaf06128a5b5451dccf7c242deaa31420b055716481"}, + {file = "coverage-6.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:0e34247274bde982bbc613894d33f9e36358179db2ed231dd101c48dd298e7b0"}, + {file = "coverage-6.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b104b6b1827d6a22483c469e3983a204bcf9c6bf7544bf90362c4654ebc2edf3"}, + {file = "coverage-6.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adf1a0d272633b21d645dd6e02e3293429c1141c7d65a58e4cbcd592d53b8e01"}, + {file = "coverage-6.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff9832434a9193fbd716fbe05f9276484e18d26cc4cf850853594bb322807ac3"}, + {file = "coverage-6.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:923f9084d7e1d31b5f74c92396b05b18921ed01ee5350402b561a79dce3ea48d"}, + {file = "coverage-6.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d64304acf79766e650f7acb81d263a3ea6e2d0d04c5172b7189180ff2c023c"}, + {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fc294de50941d3da66a09dca06e206297709332050973eca17040278cb0918ff"}, + {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a42eaaae772f14a5194f181740a67bfd48e8806394b8c67aa4399e09d0d6b5db"}, + {file = "coverage-6.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4822327b35cb032ff16af3bec27f73985448f08e874146b5b101e0e558b613dd"}, + {file = "coverage-6.4.3-cp39-cp39-win32.whl", hash = "sha256:f217850ac0e046ede611312703423767ca032a7b952b5257efac963942c055de"}, + {file = "coverage-6.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0a84376e4fd13cebce2c0ef8c2f037929c8307fb94af1e5dbe50272a1c651b5d"}, + {file = "coverage-6.4.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:068d6f2a893af838291b8809c876973d885543411ea460f3e6886ac0ee941732"}, + {file = "coverage-6.4.3.tar.gz", hash = "sha256:ec2ae1f398e5aca655b7084392d23e80efb31f7a660d2eecf569fb9f79b3fb94"}, ] coveralls = [ - {file = "coveralls-3.2.0-py2.py3-none-any.whl", hash = "sha256:aedfcc5296b788ebaf8ace8029376e5f102f67c53d1373f2e821515c15b36527"}, - {file = "coveralls-3.2.0.tar.gz", hash = "sha256:15a987d9df877fff44cd81948c5806ffb6eafb757b3443f737888358e96156ee"}, + {file = "coveralls-3.3.1-py2.py3-none-any.whl", hash = "sha256:f42015f31d386b351d4226389b387ae173207058832fbf5c8ec4b40e27b16026"}, + {file = "coveralls-3.3.1.tar.gz", hash = "sha256:b32a8bb5d2df585207c119d6c01567b81fba690c9c10a753bfe27a335bfc43ea"}, +] +darker = [ + {file = "darker-1.5.0-py3-none-any.whl", hash = "sha256:effd451a364d603578c9df569cc4ab72900b4bb3ffb7b918160ff559ef8af892"}, + {file = "darker-1.5.0.tar.gz", hash = "sha256:a23a917b9abee0725ba68da5f564ed25dd4e63eab6dc5a43d9e2f88b7c19899e"}, +] +deprecated = [ + {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, + {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, ] distlib = [ - {file = "distlib-0.3.2-py2.py3-none-any.whl", hash = "sha256:23e223426b28491b1ced97dc3bbe183027419dfc7982b4fa2f05d5f3ff10711c"}, - {file = "distlib-0.3.2.zip", hash = "sha256:106fef6dc37dd8c0e2c0a60d3fca3e77460a48907f335fa28420463a6f799736"}, + {file = "distlib-0.3.5-py2.py3-none-any.whl", hash = "sha256:b710088c59f06338ca514800ad795a132da19fda270e3ce4affc74abf955a26c"}, + {file = "distlib-0.3.5.tar.gz", hash = "sha256:a7f75737c70be3b25e2bee06288cec4e4c221de18455b2dd037fe2a795cab2fe"}, ] django = [ - {file = "Django-3.2.7-py3-none-any.whl", hash = "sha256:e93c93565005b37ddebf2396b4dc4b6913c1838baa82efdfb79acedd5816c240"}, - {file = "Django-3.2.7.tar.gz", hash = "sha256:95b318319d6997bac3595517101ad9cc83fe5672ac498ba48d1a410f47afecd2"}, + {file = "Django-3.2.15-py3-none-any.whl", hash = "sha256:115baf5049d5cf4163e43492cdc7139c306ed6d451e7d3571fe9612903903713"}, + {file = "Django-3.2.15.tar.gz", hash = "sha256:f71934b1a822f14a86c9ac9634053689279cd04ae69cb6ade4a59471b886582b"}, ] django-axes = [ - {file = "django-axes-5.24.0.tar.gz", hash = "sha256:dadee869826b6f5061d1e77369770f27008aaac7e9d6cf4eb1b0f8f7dd802691"}, - {file = "django_axes-5.24.0-py3-none-any.whl", hash = "sha256:4d7b8bef6c1094aaa94abef12a7085b4fd63b933a4010d1c82f9f120b50c19d1"}, + {file = "django-axes-5.36.0.tar.gz", hash = "sha256:bac08a7047fde26ffb54813c971fd40eeadb4ecb8d342a6e47d53de666d1a792"}, + {file = "django_axes-5.36.0-py3-none-any.whl", hash = "sha256:466e6ed1affd0866c78f245ee658d2619f74250aca5856852d86e61dba400eda"}, ] django-ipware = [ - {file = "django-ipware-4.0.0.tar.gz", hash = "sha256:1294f916f3b3475e40e1b0ec1bd320aa2397978eae672721c81cbc2ed517e9ee"}, - {file = "django_ipware-4.0.0-py2.py3-none-any.whl", hash = "sha256:116bd0d7940f09bf7ffd465943992e23d87e772a9d6c0d3a57b74040589a383b"}, + {file = "django-ipware-4.0.2.tar.gz", hash = "sha256:602a58325a4808bd19197fef2676a0b2da2df40d0ecf21be414b2ff48c72ad05"}, + {file = "django_ipware-4.0.2-py2.py3-none-any.whl", hash = "sha256:878dbb06a87e25550798e9ef3204ed70a200dd8b15e47dcef848cf08244f04c9"}, ] django-redis = [ - {file = "django-redis-5.0.0.tar.gz", hash = "sha256:048f665bbe27f8ff2edebae6aa9c534ab137f1e8fa7234147ef470df3f3aa9b8"}, - {file = "django_redis-5.0.0-py3-none-any.whl", hash = "sha256:97739ca9de3f964c51412d1d7d8aecdfd86737bb197fce6e1ff12620c63c97ee"}, + {file = "django-redis-5.2.0.tar.gz", hash = "sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de"}, + {file = "django_redis-5.2.0-py3-none-any.whl", hash = "sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026"}, ] django-yunohost-integration = [ - {file = "django_yunohost_integration-0.2.0-py3-none-any.whl", hash = "sha256:0ff205a2a32ef95ed0ae6f523aa1130e8005ad9b7807c76b18e4ef64d86f8b79"}, - {file = "django_yunohost_integration-0.2.0.tar.gz", hash = "sha256:4f6583da67a54067a6940786fc5d14e1efa9c347bf102dfb68f4bdb9f75a8e4e"}, + {file = "django_yunohost_integration-0.2.5-py3-none-any.whl", hash = "sha256:b5f9beea73515ffb8816644cde766cdd0170ce75441ceb9ac11e185f40470186"}, + {file = "django_yunohost_integration-0.2.5.tar.gz", hash = "sha256:2cade1dc6d77974139624883475dfe360fe04a86335b635f1fac2401acae56d8"}, ] docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] filelock = [ - {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, - {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, + {file = "filelock-3.8.0-py3-none-any.whl", hash = "sha256:617eb4e5eedc82fc5f47b6d61e4d11cb837c56cb4544e39081099fa17ad109d4"}, + {file = "filelock-3.8.0.tar.gz", hash = "sha256:55447caa666f2198c5b6b13a26d2084d26fa5b115c00d065664b2124680c4edc"}, ] flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] -flynt = [ - {file = "flynt-0.69-py3-none-any.whl", hash = "sha256:5bc49abd71891afbc2400f22f040ba9f23259fe03f9049dd62a2de8953248ce7"}, - {file = "flynt-0.69.tar.gz", hash = "sha256:42de12dd29e66cc067cda8a2c1fb34fb79c0b14b0c48cd7cdcbc7c5a84578adf"}, + {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, + {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, ] gunicorn = [ + {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, ] idna = [ - {file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"}, - {file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"}, + {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, + {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, ] importlib-metadata = [ - {file = "importlib_metadata-4.8.1-py3-none-any.whl", hash = "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15"}, - {file = "importlib_metadata-4.8.1.tar.gz", hash = "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"}, + {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, + {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] isort = [ - {file = "isort-5.9.3-py3-none-any.whl", hash = "sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"}, - {file = "isort-5.9.3.tar.gz", hash = "sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899"}, + {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, + {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] packaging = [ - {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, - {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] platformdirs = [ - {file = "platformdirs-2.3.0-py3-none-any.whl", hash = "sha256:8003ac87717ae2c7ee1ea5a84a1a61e87f3fbd16eb5aadba194ea30a9019f648"}, - {file = "platformdirs-2.3.0.tar.gz", hash = "sha256:15b056538719b1c94bdaccb29e5f81879c7f7f0f4a153f46086d155dffcd4f0f"}, + {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, + {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] psycopg2 = [ - {file = "psycopg2-2.9.1-cp36-cp36m-win32.whl", hash = "sha256:7f91312f065df517187134cce8e395ab37f5b601a42446bdc0f0d51773621854"}, - {file = "psycopg2-2.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:830c8e8dddab6b6716a4bf73a09910c7954a92f40cf1d1e702fb93c8a919cc56"}, - {file = "psycopg2-2.9.1-cp37-cp37m-win32.whl", hash = "sha256:89409d369f4882c47f7ea20c42c5046879ce22c1e4ea20ef3b00a4dfc0a7f188"}, - {file = "psycopg2-2.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7640e1e4d72444ef012e275e7b53204d7fab341fb22bc76057ede22fe6860b25"}, - {file = "psycopg2-2.9.1-cp38-cp38-win32.whl", hash = "sha256:079d97fc22de90da1d370c90583659a9f9a6ee4007355f5825e5f1c70dffc1fa"}, - {file = "psycopg2-2.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:2c992196719fadda59f72d44603ee1a2fdcc67de097eea38d41c7ad9ad246e62"}, - {file = "psycopg2-2.9.1-cp39-cp39-win32.whl", hash = "sha256:2087013c159a73e09713294a44d0c8008204d06326006b7f652bef5ace66eebb"}, - {file = "psycopg2-2.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:bf35a25f1aaa8a3781195595577fcbb59934856ee46b4f252f56ad12b8043bcf"}, - {file = "psycopg2-2.9.1.tar.gz", hash = "sha256:de5303a6f1d0a7a34b9d40e4d3bef684ccc44a49bbe3eb85e3c0bffb4a131b7c"}, + {file = "psycopg2-2.9.3-cp310-cp310-win32.whl", hash = "sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362"}, + {file = "psycopg2-2.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:d3ca6421b942f60c008f81a3541e8faf6865a28d5a9b48544b0ee4f40cac7fca"}, + {file = "psycopg2-2.9.3-cp36-cp36m-win32.whl", hash = "sha256:9572e08b50aed176ef6d66f15a21d823bb6f6d23152d35e8451d7d2d18fdac56"}, + {file = "psycopg2-2.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a81e3866f99382dfe8c15a151f1ca5fde5815fde879348fe5a9884a7c092a305"}, + {file = "psycopg2-2.9.3-cp37-cp37m-win32.whl", hash = "sha256:cb10d44e6694d763fa1078a26f7f6137d69f555a78ec85dc2ef716c37447e4b2"}, + {file = "psycopg2-2.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4295093a6ae3434d33ec6baab4ca5512a5082cc43c0505293087b8a46d108461"}, + {file = "psycopg2-2.9.3-cp38-cp38-win32.whl", hash = "sha256:34b33e0162cfcaad151f249c2649fd1030010c16f4bbc40a604c1cb77173dcf7"}, + {file = "psycopg2-2.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:0762c27d018edbcb2d34d51596e4346c983bd27c330218c56c4dc25ef7e819bf"}, + {file = "psycopg2-2.9.3-cp39-cp39-win32.whl", hash = "sha256:8cf3878353cc04b053822896bc4922b194792df9df2f1ad8da01fb3043602126"}, + {file = "psycopg2-2.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c"}, + {file = "psycopg2-2.9.3.tar.gz", hash = "sha256:8e841d1bf3434da985cc5ef13e6f75c8981ced601fd70cc6bf33351b91562981"}, ] py = [ - {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, - {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, + {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, + {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, ] pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, + {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, + {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] pyparsing = [ - {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, + {file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"}, ] pytest-cov = [ - {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, - {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, +] +pytest-darker = [ + {file = "pytest_darker-0.1.2-py3-none-any.whl", hash = "sha256:ec7bad719510f0ac2d3d9aeb698cf6d5fb88b76e43b0bc1ee0cfb125332abcfd"}, + {file = "pytest_darker-0.1.2.tar.gz", hash = "sha256:79d725b55e346bfb00304485184ba978723d99c4e475d73547074303255f7544"}, ] pytest-django = [ - {file = "pytest-django-4.4.0.tar.gz", hash = "sha256:b5171e3798bf7e3fc5ea7072fe87324db67a4dd9f1192b037fed4cc3c1b7f455"}, - {file = "pytest_django-4.4.0-py3-none-any.whl", hash = "sha256:65783e78382456528bd9d79a35843adde9e6a47347b20464eb2c885cb0f1f606"}, + {file = "pytest-django-4.5.2.tar.gz", hash = "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2"}, + {file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"}, ] python-stdnum = [ - {file = "python-stdnum-1.16.tar.gz", hash = "sha256:4248d898042a801fc4eff96fbfe4bf63a43324854efe3b5534718c1c195c6f43"}, - {file = "python_stdnum-1.16-py2.py3-none-any.whl", hash = "sha256:2e2c56c548ca166b95547a8d748f4d71320a5b4896960717c8e6380e08d993a5"}, + {file = "python-stdnum-1.17.tar.gz", hash = "sha256:374e2b5e13912ccdbf50b0b23fca2c3e0531174805c32d74e145f37756328340"}, + {file = "python_stdnum-1.17-py2.py3-none-any.whl", hash = "sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547"}, ] pytz = [ - {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, - {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, -] -pyupgrade = [ - {file = "pyupgrade-2.26.0-py2.py3-none-any.whl", hash = "sha256:fcfde421775d356eb1e7da443fb23fad6dceca411d8c014acebaed1c2bfeed52"}, - {file = "pyupgrade-2.26.0.tar.gz", hash = "sha256:03eba5ee3494c334d634a272774a30b0aa28af4f5f07f1d3f5d5bedee86c5bcb"}, + {file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"}, + {file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"}, ] redis = [ - {file = "redis-3.5.3-py2.py3-none-any.whl", hash = "sha256:432b788c4530cfe16d8d943a09d40ca6c16149727e4afe8c2c9d5580c59d9f24"}, - {file = "redis-3.5.3.tar.gz", hash = "sha256:0e7e0cfca8660dea8b7d5cd8c4f6c5e29e11f31158c0b0ae91a397f00e5a05a2"}, -] -regex = [ - {file = "regex-2021.8.28-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2"}, - {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a"}, - {file = "regex-2021.8.28-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0"}, - {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb"}, - {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a"}, - {file = "regex-2021.8.28-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308"}, - {file = "regex-2021.8.28-cp310-cp310-win32.whl", hash = "sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed"}, - {file = "regex-2021.8.28-cp310-cp310-win_amd64.whl", hash = "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8"}, - {file = "regex-2021.8.28-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c"}, - {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c"}, - {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13"}, - {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0"}, - {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1"}, - {file = "regex-2021.8.28-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f"}, - {file = "regex-2021.8.28-cp36-cp36m-win32.whl", hash = "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354"}, - {file = "regex-2021.8.28-cp36-cp36m-win_amd64.whl", hash = "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645"}, - {file = "regex-2021.8.28-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a"}, - {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e"}, - {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892"}, - {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791"}, - {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"}, - {file = "regex-2021.8.28-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906"}, - {file = "regex-2021.8.28-cp37-cp37m-win32.whl", hash = "sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a"}, - {file = "regex-2021.8.28-cp37-cp37m-win_amd64.whl", hash = "sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc"}, - {file = "regex-2021.8.28-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd"}, - {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797"}, - {file = "regex-2021.8.28-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f"}, - {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256"}, - {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b"}, - {file = "regex-2021.8.28-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e"}, - {file = "regex-2021.8.28-cp38-cp38-win32.whl", hash = "sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d"}, - {file = "regex-2021.8.28-cp38-cp38-win_amd64.whl", hash = "sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2"}, - {file = "regex-2021.8.28-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468"}, - {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb"}, - {file = "regex-2021.8.28-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d"}, - {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983"}, - {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8"}, - {file = "regex-2021.8.28-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed"}, - {file = "regex-2021.8.28-cp39-cp39-win32.whl", hash = "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374"}, - {file = "regex-2021.8.28-cp39-cp39-win_amd64.whl", hash = "sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73"}, - {file = "regex-2021.8.28.tar.gz", hash = "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1"}, + {file = "redis-4.3.4-py3-none-any.whl", hash = "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54"}, + {file = "redis-4.3.4.tar.gz", hash = "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880"}, ] requests = [ - {file = "requests-2.26.0-py2.py3-none-any.whl", hash = "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24"}, - {file = "requests-2.26.0.tar.gz", hash = "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"}, + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -1001,68 +988,123 @@ sqlparse = [ {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, ] -tokenize-rt = [ - {file = "tokenize_rt-4.1.0-py2.py3-none-any.whl", hash = "sha256:b37251fa28c21e8cce2e42f7769a35fba2dd2ecafb297208f9a9a8add3ca7793"}, - {file = "tokenize_rt-4.1.0.tar.gz", hash = "sha256:ab339b5ff829eb5e198590477f9c03c84e762b3e455e74c018956e7e326cbc70"}, -] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] tomli = [ - {file = "tomli-1.2.1-py3-none-any.whl", hash = "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f"}, - {file = "tomli-1.2.1.tar.gz", hash = "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442"}, + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] tox = [ - {file = "tox-3.24.3-py2.py3-none-any.whl", hash = "sha256:9fbf8e2ab758b2a5e7cb2c72945e4728089934853076f67ef18d7575c8ab6b88"}, - {file = "tox-3.24.3.tar.gz", hash = "sha256:c6c4e77705ada004283610fd6d9ba4f77bc85d235447f875df9f0ba1bc23b634"}, + {file = "tox-3.25.1-py2.py3-none-any.whl", hash = "sha256:c38e15f4733683a9cc0129fba078633e07eb0961f550a010ada879e95fb32632"}, + {file = "tox-3.25.1.tar.gz", hash = "sha256:c138327815f53bc6da4fe56baec5f25f00622ae69ef3fe4e1e385720e22486f9"}, ] typed-ast = [ - {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, - {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, - {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"}, - {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"}, - {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"}, - {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"}, - {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"}, - {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"}, - {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"}, - {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"}, - {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"}, - {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"}, - {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"}, - {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"}, - {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"}, - {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"}, - {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"}, - {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"}, - {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"}, - {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"}, - {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"}, - {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"}, - {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"}, - {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"}, - {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"}, - {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"}, - {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"}, - {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"}, - {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, - {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, + {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, + {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, + {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, + {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, + {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, + {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, + {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, + {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, + {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, + {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, + {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, + {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, + {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, + {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, + {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, + {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] typing-extensions = [ - {file = "typing_extensions-3.10.0.2-py2-none-any.whl", hash = "sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7"}, - {file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"}, - {file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"}, + {file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"}, + {file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"}, ] urllib3 = [ - {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"}, - {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, + {file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"}, + {file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"}, ] virtualenv = [ - {file = "virtualenv-20.7.2-py2.py3-none-any.whl", hash = "sha256:e4670891b3a03eb071748c569a87cceaefbf643c5bac46d996c5a45c34aa0f06"}, - {file = "virtualenv-20.7.2.tar.gz", hash = "sha256:9ef4e8ee4710826e98ff3075c9a4739e2cb1040de6a2a8d35db0055840dc96a0"}, + {file = "virtualenv-20.16.2-py2.py3-none-any.whl", hash = "sha256:635b272a8e2f77cb051946f46c60a54ace3cb5e25568228bd6b57fc70eca9ff3"}, + {file = "virtualenv-20.16.2.tar.gz", hash = "sha256:0ef5be6d07181946891f5abc8047fda8bc2f0b4b9bf222c64e6e8963baee76db"}, +] +wrapt = [ + {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, + {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, + {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, + {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, + {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, + {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, + {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, + {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, + {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, + {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, + {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, + {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, + {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, + {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, + {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, + {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, + {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, + {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, + {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, + {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, + {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, + {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, + {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, + {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, + {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, + {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, + {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, + {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, + {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, + {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, + {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, + {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.5.0-py3-none-any.whl", hash = "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3"}, - {file = "zipp-3.5.0.tar.gz", hash = "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4"}, + {file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"}, + {file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"}, ] diff --git a/pyproject.toml b/pyproject.toml index 884d745..9ce7b39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,13 +1,16 @@ [tool.poetry] name = "django_example_ynh" -version = "v0.2.0" +version = "0.3.0" description = "Demo YunoHost Application to demonstrate the integration of a Django project under YunoHost." authors = ["JensDiemer "] license = "GPL" homepage = "https://github.com/YunoHost-Apps/django_example_ynh" +[tool.poetry.urls] +"Bug Tracker" = "https://github.com/YunoHost-Apps/django_example_ynh/issues" + [tool.poetry.dependencies] -python = ">=3.7,<4.0.0" +python = ">=3.7,<4.0.0" # TODO: Update to >=3.8 after YunoHost updates to Bullseye django_yunohost_integration = {version = "*", extras = ["ynh"]} [tool.poetry.dev-dependencies] @@ -17,30 +20,43 @@ tox = "*" pytest = "*" pytest-cov = "*" pytest-django = "*" +pytest-darker = "*" # https://github.com/akaihola/pytest-darker coveralls = "*" isort = "*" flake8 = "*" -flynt = "*" -black = "*" -pyupgrade = "*" [build-system] 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' skip_glob=["*/htmlcov/*","*/migrations/*"] -multi_line_output=3 -include_trailing_comma=true -known_first_party=[] -no_lines_before="LOCALFOLDER" -default_section="THIRDPARTY" -sections=["FUTURE","STDLIB","THIRDPARTY","FIRSTPARTY","LOCALFOLDER"] +known_first_party=['django_yunohost_integration'] +line_length=100 lines_after_imports=2 @@ -56,7 +72,6 @@ norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov" # --full-trace # -p no:warnings addopts = """ - --import-mode=importlib --reuse-db --nomigrations --cov=. @@ -65,19 +80,23 @@ addopts = """ --cov-report xml --no-cov-on-fail --showlocals + --darker --doctest-modules --failed-first - --last-failed-no-failures all --new-first """ +[tool.coverage.run] +omit = [".*"] + + [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 = py{37,38,39,310} skip_missing_interpreters = True [testenv] diff --git a/scripts/_common.sh b/scripts/_common.sh index 0e3da73..b95ce9c 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -20,6 +20,12 @@ final_path=/opt/yunohost/$app log_path=/var/log/$app log_file="${log_path}/django_example_ynh.log" +# XXX: Is this okay? +adminmail="${admin}@${domain}" + +# Default: settings.DEBUG=False +django_debug="False" + #================================================= # COMMON VARIABLES #================================================= diff --git a/scripts/change_url b/scripts/change_url index 2b32057..98f98d6 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -25,7 +25,6 @@ new_path=$YNH_APP_NEW_PATH ynh_script_progression --message="Loading installation settings..." admin=$(ynh_app_setting_get --app="$app" --key=admin) -is_public=$(ynh_app_setting_get --app="$app" --key=is_public) public_path=$(ynh_app_setting_get --app="$app" --key=public_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path) log_path=$(ynh_app_setting_get --app="$app" --key=log_path) @@ -113,29 +112,9 @@ fi #================================================= # MODIFY SETTINGS #================================================= -ynh_script_progression --message="Modify PyInventory's config file..." +ynh_script_progression --message="Modify django-fmd's config file..." -# save old settings file -settings="$final_path/settings.py" -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_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" -ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings" -ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings" -ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings" -ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings" - -# Difference to install/upgrade scripts: Use $new_domain and $new_path here: -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$new_domain" --target_file="$settings" -ynh_replace_string --match_string="__PATH_URL__" --replace_string="$new_path" --target_file="$settings" - -# Recalculate and store the config file checksum into the app settings -ynh_store_file_checksum --file="$settings" +ynh_add_config --template="settings.py" --destination="$final_path/settings.py" #================================================= # GENERIC FINALISATION diff --git a/scripts/install b/scripts/install index ef903ce..727dad1 100755 --- a/scripts/install +++ b/scripts/install @@ -40,7 +40,6 @@ touch "${log_file}" ynh_script_progression --message="Storing installation settings..." ynh_app_setting_set --app="$app" --key=admin --value="$admin" -ynh_app_setting_set --app="$app" --key=is_public --value="$is_public" ynh_app_setting_set --app="$app" --key=public_path --value="$public_path" ynh_app_setting_set --app="$app" --key=final_path --value="$final_path" ynh_app_setting_set --app="$app" --key=log_path --value="$log_file" @@ -51,19 +50,25 @@ ynh_app_setting_set --app="$app" --key=path --value="$path_url" # Find a free port port=$(ynh_find_port --port=8000) # Set port as application setting -# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/setting +# https://yunohost.org/en/contribute/packaging_apps/helpers +# https://github.com/YunoHost/yunohost/blob/dev/helpers/setting ynh_app_setting_set --app="$app" --key=port --value="$port" db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) admin_mail=$(ynh_user_get_info --username="$admin" --key=mail) + redis_db=$(ynh_redis_get_free_db) +ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" + +# Always deactivate settings.DEBUG: +ynh_app_setting_set --app=$app --key=django_debug --value="False" #================================================= # STANDARD MODIFICATIONS #================================================= # 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" @@ -87,7 +92,8 @@ ynh_psql_setup_db --db_user="$db_user" --db_name="$db_name" ynh_script_progression --message="Configuring nginx web server..." # Create a dedicated nginx config -# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx +# https://yunohost.org/en/contribute/packaging_apps/helpers +# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx ynh_add_nginx_config "public_path" "port" #================================================= @@ -101,9 +107,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,8 +123,9 @@ 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 pip - ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" + 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 + ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" ) #================================================= @@ -121,39 +133,15 @@ chown -R "$app:" "$final_path" # ================================================ ynh_script_progression --message="Create project configuration files..." -gunicorn_conf="$final_path/gunicorn.conf.py" -cp "../conf/gunicorn.conf.py" "$gunicorn_conf" -ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf" -ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf" -ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf" -ynh_store_file_checksum --file="$gunicorn_conf" +ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py" -cp ../conf/manage.py "$final_path/manage.py" +ynh_add_config --template="manage.py" --destination="$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_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" -ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings" -ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings" -ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings" -ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings" - -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings" -ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings" - -# Calculate and store the config file checksum into the app settings -ynh_store_file_checksum --file="$settings" - -ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db" - -cp ../conf/setup_user.py "$final_path/setup_user.py" -cp ../conf/urls.py "$final_path/urls.py" -cp ../conf/wsgi.py "$final_path/wsgi.py" +ynh_add_config --template="settings.py" --destination="$final_path/settings.py" +ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py" +ynh_add_config --template="urls.py" --destination="$final_path/urls.py" +ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py" touch "$final_path/local_settings.py" @@ -162,25 +150,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 @@ -205,16 +189,21 @@ 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 #================================================= ynh_script_progression --message="Configuring a systemd service..." -# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd -ynh_add_systemd_config --service="$app" --template="django_example_ynh.service" +# https://yunohost.org/en/contribute/packaging_apps/helpers +# https://github.com/YunoHost/yunohost/blob/dev/helpers/systemd +ynh_add_systemd_config --service="$app" --template="systemd.service" #================================================= # SETUP SSOWAT @@ -232,7 +221,7 @@ fi #================================================= # Start django_example_ynh via systemd #================================================= -ynh_script_progression --message="Starting PyInventory's services..." --weight=5 +ynh_script_progression --message="Starting django_example_ynh's services..." --weight=5 ynh_systemd_action --service_name="$app" --action="start" diff --git a/scripts/restore b/scripts/restore index dcd5ee0..34d464f 100755 --- a/scripts/restore +++ b/scripts/restore @@ -20,8 +20,8 @@ ynh_abort_if_errors #================================================= ynh_script_progression --message="Loading settings..." -public_path=$(ynh_app_setting_get --app="$app" --key=public_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path) +public_path=$(ynh_app_setting_get --app="$app" --key=public_path) db_name=$(ynh_app_setting_get --app="$app" --key=db_name) db_user=$db_name db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) @@ -34,8 +34,6 @@ path_url=$(ynh_app_setting_get --app="$app" --key=path) #================================================= ynh_script_progression --message="Validating restoration parameters..." -ynh_webpath_available --domain=$domain --path_url=$path_url \ - || ynh_die --message="Path not available: ${domain}${path_url}" test ! -d $final_path \ || ynh_die --message="There is already a directory: $final_path " @@ -52,10 +50,8 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= ynh_script_progression --message="Restoring the app main directory..." -ynh_restore_file --origin_path="$public_path" ynh_restore_file --origin_path="$final_path" - -touch "$final_path/local_settings.py" +ynh_restore_file --origin_path="$public_path" #================================================= # RECREATE THE DEDICATED USER @@ -70,7 +66,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,10 +74,33 @@ 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" +#================================================= +# REINSTALL PYTHON VIRTUALENV +# Maybe the backup contains a other Python version +#================================================= +ynh_script_progression --message="Upgrade Python virtualenv..." --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" +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/python3 -m ensurepip + ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools + ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" +) + #================================================= # RESTORE THE PostgreSQL DATABASE #================================================= @@ -115,6 +134,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 #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 9ed9121..f639cbb 100755 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -13,7 +13,6 @@ source /usr/share/yunohost/helpers ynh_script_progression --message="Loading installation settings..." admin=$(ynh_app_setting_get --app="$app" --key=admin) -is_public=$(ynh_app_setting_get --app="$app" --key=is_public) public_path=$(ynh_app_setting_get --app="$app" --key=public_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path) log_path=$(ynh_app_setting_get --app="$app" --key=log_path) @@ -22,10 +21,16 @@ 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) +django_debug=$(ynh_app_setting_get --app="$app" --key=django_debug) + #================================================= # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP #================================================= @@ -49,13 +54,21 @@ ynh_script_progression --message="Stopping systemd services..." --weight=5 ynh_systemd_action --service_name="$app" --action="stop" +#================================================= +# Manage old settings +#================================================= + +# Always deactivate settings.DEBUG: +ynh_app_setting_set --app=$app --key=django_debug --value="False" + #================================================= # NGINX CONFIGURATION #================================================= ynh_script_progression --message="Upgrading nginx web server configuration..." # Create a dedicated nginx config -# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx +# https://yunohost.org/en/contribute/packaging_apps/helpers +# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx ynh_add_nginx_config "public_path" "port" #================================================= @@ -63,7 +76,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" @@ -80,14 +93,19 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell #================================================= ynh_script_progression --message="Configuring a systemd service..." -ynh_add_systemd_config --service="$app" --template="django_example_ynh.service" +ynh_add_systemd_config --service="$app" --template="systemd.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 "${final_path}/venv" cp ../conf/requirements.txt "$final_path/requirements.txt" chown -R "$app:" "$final_path" @@ -96,8 +114,9 @@ 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 pip - ynh_exec_as $app $final_path/venv/bin/pip install -r "$final_path/requirements.txt" + 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 + ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" ) #================================================= @@ -105,74 +124,36 @@ chown -R "$app:" "$final_path" # ================================================ ynh_script_progression --message="Create project configuration files..." -gunicorn_conf="$final_path/gunicorn.conf.py" -ynh_backup_if_checksum_is_different --file="$gunicorn_conf" -cp "../conf/gunicorn.conf.py" "$gunicorn_conf" -ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf" -ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf" -ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf" -ynh_store_file_checksum --file="$gunicorn_conf" +ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py" -ynh_backup_if_checksum_is_different --file="$final_path/manage.py" -cp ../conf/manage.py "$final_path/manage.py" +ynh_add_config --template="manage.py" --destination="$final_path/manage.py" chmod +x "$final_path/manage.py" -# save old settings file -settings="$final_path/settings.py" -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_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" -ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings" -ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings" -ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings" -ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings" - -ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings" -ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings" - -# Recalculate and store the config file checksum into the app settings -ynh_store_file_checksum --file="$settings" - -ynh_backup_if_checksum_is_different --file="$final_path/setup_user.py" -cp ../conf/setup_user.py "$final_path/setup_user.py" - -ynh_backup_if_checksum_is_different --file="$final_path/urls.py" -cp ../conf/urls.py "$final_path/urls.py" - -ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py" -cp ../conf/wsgi.py "$final_path/wsgi.py" - -touch "$final_path/local_settings.py" +ynh_add_config --template="settings.py" --destination="$final_path/settings.py" +ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py" +ynh_add_config --template="urls.py" --destination="$final_path/urls.py" +ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py" #================================================= # MIGRATE PYINVENTORY #================================================= 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 @@ -197,13 +178,17 @@ 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 django_example_ynh via systemd #================================================= -ynh_script_progression --message="Starting PyInventory's services..." --weight=5 +ynh_script_progression --message="Starting django_example_ynh's services..." --weight=5 ynh_systemd_action --service_name="$app" --action="start" diff --git a/tests/test_django_project.py b/tests/test_django_project.py index 6b0f306..91ad6ab 100644 --- a/tests/test_django_project.py +++ b/tests/test_django_project.py @@ -4,8 +4,8 @@ from django.conf import settings from django.contrib.auth.models import User from django.test import override_settings from django.test.testcases import TestCase -from django.urls import NoReverseMatch from django.urls.base import reverse + from django_yunohost_integration.test_utils import generate_basic_auth from django_yunohost_integration.views import request_media_debug_view @@ -21,8 +21,8 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): def test_settings(self): assert settings.PATH_URL == 'app_path' - assert str(settings.FINAL_HOME_PATH).endswith('/local_test/opt_yunohost') - assert str(settings.FINAL_WWW_PATH).endswith('/local_test/var_www') + assert str(settings.FINALPATH).endswith('/local_test/opt_yunohost') + assert str(settings.PUBLIC_PATH).endswith('/local_test/var_www') assert str(settings.LOG_FILE).endswith('/local_test/var_log_django_example_ynh.log') assert settings.ROOT_URLCONF == 'urls' @@ -30,19 +30,24 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): def test_urls(self): assert reverse('admin:index') == '/app_path/' - # The django_yunohost_integration debug view should not be avaiable: - with self.assertRaises(NoReverseMatch): - reverse(request_media_debug_view) - - # 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/' - ) + # In example app, the debug view is in urls.py: + assert reverse(request_media_debug_view) == '/app_path/debug/' def test_auth(self): - response = self.client.get('/app_path/') - self.assertRedirects(response, expected_url='/app_path/login/?next=/app_path/') + # SecurityMiddleware should redirects all non-HTTPS requests to HTTPS: + assert settings.SECURE_SSL_REDIRECT is True + response = self.client.get('/app_path/', secure=False) + self.assertRedirects( + response, + status_code=301, # permanent redirect + expected_url='https://testserver/app_path/', + fetch_redirect_response=False, + ) + + response = self.client.get('/app_path/', secure=True) + self.assertRedirects( + response, expected_url='/app_path/login/?next=/app_path/', fetch_redirect_response=False + ) def test_create_unknown_user(self): assert User.objects.count() == 0 @@ -54,6 +59,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): HTTP_REMOTE_USER='test', HTTP_AUTH_USER='test', HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + secure=True, ) assert User.objects.count() == 1 @@ -66,7 +72,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): self.assert_html_parts( response, parts=( - f'Site administration', + '

Django administration

', 'test', ), ) @@ -82,6 +88,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): HTTP_REMOTE_USER='test', HTTP_AUTH_USER='foobar', # <<< wrong user name HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + secure=True, ) assert User.objects.count() == 1 @@ -106,6 +113,7 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase): HTTP_REMOTE_USER='test', HTTP_AUTH_USER='test', HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', + secure=True, ) assert User.objects.count() == 1 @@ -128,7 +136,11 @@ 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', # <<< wrong user name + password='test123', + ), + secure=True, ) assert User.objects.count() == 1 diff --git a/tests/test_lint.py b/tests/test_lint.py deleted file mode 100644 index 003dc76..0000000 --- a/tests/test_lint.py +++ /dev/null @@ -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) diff --git a/tests/test_project_setup.py b/tests/test_project_setup.py index 221e8a1..9d4e7a2 100644 --- a/tests/test_project_setup.py +++ b/tests/test_project_setup.py @@ -3,7 +3,7 @@ import shutil import subprocess from pathlib import Path -import django_yunohost_integration +import tomli PACKAGE_ROOT = Path(__file__).parent.parent @@ -18,11 +18,16 @@ def assert_file_contains_string(file_path, string): def test_version(): - version = django_yunohost_integration.__version__ + pyproject_toml_path = Path(PACKAGE_ROOT, 'pyproject.toml') + pyproject_toml = tomli.loads(pyproject_toml_path.read_text(encoding='UTF-8')) + version = pyproject_toml['tool']['poetry']['version'] + assert '~ynh' not in version + assert version[0].isdigit() - assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh') - assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'django_yunohost_integration = "=={version}"') - assert_file_contains_string(file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh') + assert_file_contains_string( + file_path=Path(PACKAGE_ROOT, 'manifest.json'), + string=f'"version": "{version}~ynh', + ) def test_poetry_check(): @@ -30,7 +35,7 @@ def test_poetry_check(): output = subprocess.check_output( [poerty_bin, 'check'], - universal_newlines=True, + text=True, env=os.environ, stderr=subprocess.STDOUT, cwd=str(PACKAGE_ROOT),