mirror of
https://github.com/YunoHost-Apps/pyinventory_ynh.git
synced 2024-09-03 20:16:09 +02:00
commit
7305e46719
43 changed files with 2750 additions and 3824 deletions
16
.github/workflows/package_linter.yml
vendored
16
.github/workflows/package_linter.yml
vendored
|
@ -15,18 +15,15 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
# https://github.com/marketplace/actions/checkout
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- name: Set up Python
|
||||||
# https://github.com/marketplace/actions/cache
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/
|
python-version: '3.9'
|
||||||
key: dot-cache-files
|
|
||||||
|
|
||||||
- name: 'Install dependencies'
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
pip install toml
|
pip install toml
|
||||||
|
|
||||||
- name: 'Clone YunoHost apps package linter'
|
- name: 'Clone YunoHost apps package linter'
|
||||||
|
@ -34,8 +31,7 @@ jobs:
|
||||||
git clone --depth=1 https://github.com/YunoHost/package_linter ~/package_linter
|
git clone --depth=1 https://github.com/YunoHost/package_linter ~/package_linter
|
||||||
|
|
||||||
- name: 'Install requirements'
|
- name: 'Install requirements'
|
||||||
run: |
|
run: pip3 install toml
|
||||||
pip3 install toml
|
|
||||||
|
|
||||||
- name: 'Run linter'
|
- name: 'Run linter'
|
||||||
run: |
|
run: |
|
||||||
|
|
69
.github/workflows/pytest.yml
vendored
69
.github/workflows/pytest.yml
vendored
|
@ -1,69 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
name: pytest
|
|
||||||
|
|
||||||
on:
|
|
||||||
# Allow to manually trigger the workflow
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 8 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python-version: ["3.11", "3.10", "3.9"]
|
|
||||||
env:
|
|
||||||
PYTHONUNBUFFERED: 1
|
|
||||||
PYTHONWARNINGS: always
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
# https://github.com/marketplace/actions/checkout
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: 'fetch master and testing (for Darker/Black)'
|
|
||||||
run: |
|
|
||||||
git fetch origin master
|
|
||||||
git fetch origin testing
|
|
||||||
|
|
||||||
- name: 'Set up Python ${{ matrix.python-version }}'
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '${{ matrix.python-version }}'
|
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
|
||||||
# https://github.com/marketplace/actions/cache
|
|
||||||
with:
|
|
||||||
path: ~/.cache/
|
|
||||||
key: dot-cache-files
|
|
||||||
|
|
||||||
- name: 'Install package'
|
|
||||||
run: |
|
|
||||||
pip3 install poetry
|
|
||||||
make install
|
|
||||||
|
|
||||||
- name: 'List installed packages'
|
|
||||||
run: |
|
|
||||||
poetry run pip freeze
|
|
||||||
|
|
||||||
- name: 'Run tests with Python v${{ matrix.python-version }}'
|
|
||||||
run: |
|
|
||||||
make pytest
|
|
||||||
|
|
||||||
- name: 'Run Safety check'
|
|
||||||
run: |
|
|
||||||
make safety
|
|
||||||
|
|
||||||
- name: 'Upload coverage report'
|
|
||||||
uses: codecov/codecov-action@v3
|
|
||||||
# https://github.com/marketplace/actions/codecov
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: false
|
|
||||||
verbose: true
|
|
||||||
|
|
66
.github/workflows/tests.yml
vendored
Normal file
66
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
|
||||||
|
name: tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 8 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
python-version: ["3.12", "3.11", "3.10", "3.9"]
|
||||||
|
env:
|
||||||
|
PYTHONUNBUFFERED: 1
|
||||||
|
PYTHONWARNINGS: always
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
run: |
|
||||||
|
echo $GITHUB_REF $GITHUB_SHA
|
||||||
|
git clone https://github.com/$GITHUB_REPOSITORY.git .
|
||||||
|
git fetch origin $GITHUB_SHA:temporary-ci-branch
|
||||||
|
git checkout $GITHUB_SHA || (git fetch && git checkout $GITHUB_SHA)
|
||||||
|
- name: 'fetch master'
|
||||||
|
run: |
|
||||||
|
git fetch origin master
|
||||||
|
|
||||||
|
- name: 'Set up Python ${{ matrix.python-version }}'
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
# https://github.com/marketplace/actions/setup-python
|
||||||
|
with:
|
||||||
|
python-version: '${{ matrix.python-version }}'
|
||||||
|
cache: 'pip' # caching pip dependencies
|
||||||
|
cache-dependency-path: '**/requirements.dev.txt'
|
||||||
|
|
||||||
|
- name: 'Bootstrap dev venv'
|
||||||
|
# The first CLI call will create the .venv
|
||||||
|
run: |
|
||||||
|
./dev-cli.py version
|
||||||
|
|
||||||
|
- name: 'dev CLI help'
|
||||||
|
run: |
|
||||||
|
./dev-cli.py --help
|
||||||
|
|
||||||
|
- name: 'Safety'
|
||||||
|
run: |
|
||||||
|
./dev-cli.py safety
|
||||||
|
|
||||||
|
- name: 'Run tests with Python v${{ matrix.python-version }}'
|
||||||
|
run: |
|
||||||
|
.venv/bin/coverage erase
|
||||||
|
./dev-cli.py coverage
|
||||||
|
|
||||||
|
- name: 'Upload coverage report'
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
# https://github.com/marketplace/actions/codecov
|
||||||
|
with:
|
||||||
|
fail_ci_if_error: false
|
||||||
|
verbose: true
|
||||||
|
|
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -1,13 +1,17 @@
|
||||||
.*
|
.*
|
||||||
|
*.egg-info
|
||||||
|
__pycache__
|
||||||
|
/dist/
|
||||||
|
/coverage.*
|
||||||
|
/htmlcov/
|
||||||
|
*.orig
|
||||||
|
|
||||||
!.github
|
!.github
|
||||||
!.editorconfig
|
!.editorconfig
|
||||||
!.flake8
|
!.flake8
|
||||||
!.gitignore
|
!.gitignore
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
!/doc/screenshots/.gitkeep
|
!/doc/screenshots/.gitkeep
|
||||||
__pycache__
|
|
||||||
secret.txt
|
secret.txt
|
||||||
/local_test/
|
/local_test/
|
||||||
/coverage.json
|
|
||||||
/coverage.xml
|
|
||||||
/htmlcov/
|
|
||||||
|
|
65
Makefile
65
Makefile
|
@ -1,65 +0,0 @@
|
||||||
SHELL := /bin/bash
|
|
||||||
MAX_LINE_LENGTH := 100
|
|
||||||
|
|
||||||
all: help
|
|
||||||
|
|
||||||
help:
|
|
||||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9 -]+:.*?## / {printf "\033[36m%-22s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
|
||||||
|
|
||||||
check-poetry:
|
|
||||||
@if [[ "$(shell poetry --version 2>/dev/null)" == *"Poetry"* ]] ; \
|
|
||||||
then \
|
|
||||||
echo "Poetry found, ok." ; \
|
|
||||||
else \
|
|
||||||
echo 'Please install poetry first, with e.g.:' ; \
|
|
||||||
echo 'make install-poetry' ; \
|
|
||||||
exit 1 ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
install-base-req: ## Install needed base packages via apt
|
|
||||||
sudo apt install python3-pip python3-venv
|
|
||||||
|
|
||||||
install-poetry: ## install or update poetry
|
|
||||||
curl -sSL https://install.python-poetry.org | python3 -
|
|
||||||
|
|
||||||
install: check-poetry ## install project via poetry
|
|
||||||
python3 -m venv .venv
|
|
||||||
poetry install
|
|
||||||
|
|
||||||
update: check-poetry ## update the sources and installation and generate "conf/requirements.txt"
|
|
||||||
python3 -m venv .venv
|
|
||||||
poetry self update
|
|
||||||
poetry update -v
|
|
||||||
poetry install
|
|
||||||
poetry export -f requirements.txt --output conf/requirements.txt
|
|
||||||
|
|
||||||
lint: ## Run code formatters and linter
|
|
||||||
poetry run darker --check
|
|
||||||
poetry run isort --check-only .
|
|
||||||
poetry run flake8 .
|
|
||||||
|
|
||||||
fix-code-style: ## Fix code formatting
|
|
||||||
poetry run darker
|
|
||||||
poetry run isort .
|
|
||||||
|
|
||||||
tox-listenvs: check-poetry ## List all tox test environments
|
|
||||||
poetry run tox --listenvs
|
|
||||||
|
|
||||||
tox: check-poetry ## Run pytest via tox with all environments
|
|
||||||
poetry run tox
|
|
||||||
|
|
||||||
pytest: install ## Run pytest
|
|
||||||
poetry run pytest
|
|
||||||
|
|
||||||
local-test: install ## Run local_test.py to run the project locally
|
|
||||||
poetry run python3 ./local_test.py
|
|
||||||
|
|
||||||
local-diff-settings: ## Run "manage.py diffsettings" with local test
|
|
||||||
poetry run python3 local_test/opt_yunohost/manage.py diffsettings
|
|
||||||
|
|
||||||
safety: ## Run https://github.com/pyupio/safety
|
|
||||||
poetry run safety check --full-report
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
.PHONY: help check-poetry install-poetry install update local-test
|
|
166
README.md
166
README.md
|
@ -16,15 +16,17 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
[![tests](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml)
|
||||||
|
[![codecov](https://codecov.io/github/jedie/pyinventory_ynh/branch/main/graph/badge.svg)](https://app.codecov.io/github/jedie/pyinventory_ynh)
|
||||||
|
[![pyinventory_ynh @ PyPi](https://img.shields.io/pypi/v/pyinventory_ynh?label=pyinventory_ynh%20%40%20PyPi)](https://pypi.org/project/pyinventory_ynh/)
|
||||||
|
[![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/pyproject.toml)
|
||||||
|
[![License GPL-3.0-or-later](https://img.shields.io/pypi/l/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/LICENSE)
|
||||||
|
|
||||||
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
||||||
|
|
||||||
[![Integration level](https://dash.yunohost.org/integration/pyinventory.svg)](https://dash.yunohost.org/appci/app/pyinventory) [![CI Pipeline](https://ci-apps.yunohost.org/ci/badges/pyinventory.status.svg)](https://ci-apps.yunohost.org/ci/apps/pyinventory/) [![Maintain status](https://ci-apps.yunohost.org/ci/badges/pyinventory.maintain.svg)](https://dash.yunohost.org/appci/app/pyinventory)
|
[![Integration level](https://dash.yunohost.org/integration/pyinventory_ynh.svg)](https://dash.yunohost.org/appci/app/pyinventory_ynh) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.maintain.svg)
|
||||||
|
[![Install pyinventory_ynh with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=pyinventory_ynh)
|
||||||
|
|
||||||
[![pytest](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh)
|
|
||||||
|
|
||||||
![pyinventory @ PyPi](https://img.shields.io/pypi/v/pyinventory?label=pyinventory%20%40%20PyPi)
|
|
||||||
![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory)
|
|
||||||
![License GPL V3+](https://img.shields.io/pypi/l/pyinventory)
|
|
||||||
|
|
||||||
Pull requests welcome ;)
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
||||||
|
|
||||||
|
|
||||||
**Shipped version:** 0.19.2~ynh1
|
**Shipped version:** 0.19.3~ynh1
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
@ -47,161 +49,25 @@ More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
||||||
## Settings and upgrades
|
## Settings and upgrades
|
||||||
|
|
||||||
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
You can edit the file `/opt/yunohost/pyinventory/local_settings.py` to enable or disable features.
|
You can edit the file `/home/yunohost.app/django_example/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
Test sending emails:
|
Test sending emails, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh admin@yourdomain.tld
|
ssh admin@yourdomain.tld
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
root@yunohost:~# /home/yunohost.app/pyinventory/manage.py sendtestemail --admins
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
How to debug a django YunoHost app, take a look into:
|
||||||
To check current ADMINS run:
|
|
||||||
|
|
||||||
```bash
|
* https://github.com/YunoHost-Apps/django_example_ynh#developer-info
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
|
||||||
|
|
||||||
If you prefere to send error emails to a extrnal email address, just do something like this:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/pyinventory/local_settings.py
|
|
||||||
```
|
|
||||||
|
|
||||||
To check the effective settings, run this:
|
|
||||||
```bash
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py diffsettings
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
|
|
||||||
|
|
||||||
## SSO authentication
|
|
||||||
|
|
||||||
[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration):
|
|
||||||
|
|
||||||
* First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user
|
|
||||||
* All new users will be created as normal users
|
|
||||||
* Login via SSO is fully supported
|
|
||||||
* User Email, First / Last name will be updated from SSO data
|
|
||||||
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
* Report a bug about this package: https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
* Report a bug about PyInventory itself: https://github.com/jedie/PyInventory
|
|
||||||
* YunoHost website: https://yunohost.org/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Developer info
|
|
||||||
|
|
||||||
## package installation / debugging
|
|
||||||
|
|
||||||
Please send your pull request to https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
|
|
||||||
Try 'main' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Try 'testing' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
To remove call e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app remove pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Backup / remove / restore cycle, e.g.:
|
|
||||||
```bash
|
|
||||||
yunohost backup create --apps pyinventory
|
|
||||||
yunohost backup list
|
|
||||||
archives:
|
|
||||||
- pyinventory-pre-upgrade1
|
|
||||||
- 20201223-163434
|
|
||||||
yunohost app remove pyinventory
|
|
||||||
yunohost backup restore 20201223-163434 --apps pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Debug installation, e.g.:
|
|
||||||
```bash
|
|
||||||
root@yunohost:~# ls -la /var/www/pyinventory/
|
|
||||||
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/pyinventory/
|
|
||||||
total 58
|
|
||||||
drwxr-xr-x 5 pyinventory pyinventory 11 Dec 8 08:39 .
|
|
||||||
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 460 Dec 8 08:39 gunicorn.conf.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 0 Dec 8 08:39 local_settings.py
|
|
||||||
-rwxr-xr-x 1 pyinventory pyinventory 274 Dec 8 08:39 manage.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 171 Dec 8 08:39 secret.txt
|
|
||||||
drwxr-xr-x 6 pyinventory pyinventory 6 Dec 8 08:37 venv
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 115 Dec 8 08:39 wsgi.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 4737 Dec 8 08:39 settings.py
|
|
||||||
|
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py check
|
|
||||||
PyInventory v0.8.2 (Django v2.2.17)
|
|
||||||
DJANGO_SETTINGS_MODULE='settings'
|
|
||||||
PROJECT_PATH:/opt/yunohost/pyinventory/venv/lib/python3.7/site-packages
|
|
||||||
BASE_PATH:/opt/yunohost/pyinventory
|
|
||||||
System check identified no issues (0 silenced).
|
|
||||||
|
|
||||||
root@yunohost:~# tail -f /var/log/pyinventory/pyinventory.log
|
|
||||||
root@yunohost:~# cat /etc/systemd/system/pyinventory.service
|
|
||||||
|
|
||||||
root@yunohost:~# systemctl reload-or-restart pyinventory
|
|
||||||
root@yunohost:~# journalctl --unit=pyinventory --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
## local test
|
|
||||||
|
|
||||||
For quicker developing of PyInventory 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/pyinventory_ynh.git
|
|
||||||
~$ cd pyinventory_ynh/
|
|
||||||
~/pyinventory_ynh$ make
|
|
||||||
install-poetry install or update poetry
|
|
||||||
install install PyInventory via poetry
|
|
||||||
update update the sources and installation
|
|
||||||
local-test Run local_test.py to run pyinventory_ynh locally
|
|
||||||
~/pyinventory_ynh$ make install-poetry
|
|
||||||
~/pyinventory_ynh$ make install
|
|
||||||
~/pyinventory_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/`
|
|
||||||
|
|
||||||
## Documentation and resources
|
## Documentation and resources
|
||||||
|
|
||||||
|
* Official app website: <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* Official user documentation: <https://github.com/jedie/PyInventory>
|
* Official user documentation: <https://github.com/jedie/PyInventory>
|
||||||
* Official admin documentation: <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
* Official admin documentation: <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* Upstream app code repository: <https://github.com/jedie/PyInventory>
|
* Upstream app code repository: <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* YunoHost Store: <https://apps.yunohost.org/app/pyinventory>
|
* YunoHost Store: <https://apps.yunohost.org/app/pyinventory>
|
||||||
* Report a bug: <https://github.com/YunoHost-Apps/pyinventory_ynh/issues>
|
* Report a bug: <https://github.com/YunoHost-Apps/pyinventory_ynh/issues>
|
||||||
|
|
||||||
|
|
166
README_fr.md
166
README_fr.md
|
@ -16,15 +16,17 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po
|
||||||
|
|
||||||
## Vue d’ensemble
|
## Vue d’ensemble
|
||||||
|
|
||||||
|
[![tests](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml)
|
||||||
|
[![codecov](https://codecov.io/github/jedie/pyinventory_ynh/branch/main/graph/badge.svg)](https://app.codecov.io/github/jedie/pyinventory_ynh)
|
||||||
|
[![pyinventory_ynh @ PyPi](https://img.shields.io/pypi/v/pyinventory_ynh?label=pyinventory_ynh%20%40%20PyPi)](https://pypi.org/project/pyinventory_ynh/)
|
||||||
|
[![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/pyproject.toml)
|
||||||
|
[![License GPL-3.0-or-later](https://img.shields.io/pypi/l/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/LICENSE)
|
||||||
|
|
||||||
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
||||||
|
|
||||||
[![Integration level](https://dash.yunohost.org/integration/pyinventory.svg)](https://dash.yunohost.org/appci/app/pyinventory) [![CI Pipeline](https://ci-apps.yunohost.org/ci/badges/pyinventory.status.svg)](https://ci-apps.yunohost.org/ci/apps/pyinventory/) [![Maintain status](https://ci-apps.yunohost.org/ci/badges/pyinventory.maintain.svg)](https://dash.yunohost.org/appci/app/pyinventory)
|
[![Integration level](https://dash.yunohost.org/integration/pyinventory_ynh.svg)](https://dash.yunohost.org/appci/app/pyinventory_ynh) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.maintain.svg)
|
||||||
|
[![Install pyinventory_ynh with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=pyinventory_ynh)
|
||||||
|
|
||||||
[![pytest](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh)
|
|
||||||
|
|
||||||
![pyinventory @ PyPi](https://img.shields.io/pypi/v/pyinventory?label=pyinventory%20%40%20PyPi)
|
|
||||||
![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory)
|
|
||||||
![License GPL V3+](https://img.shields.io/pypi/l/pyinventory)
|
|
||||||
|
|
||||||
Pull requests welcome ;)
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
|
||||||
More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
||||||
|
|
||||||
|
|
||||||
**Version incluse :** 0.19.2~ynh1
|
**Version incluse :** 0.19.3~ynh1
|
||||||
|
|
||||||
## Captures d’écran
|
## Captures d’écran
|
||||||
|
|
||||||
|
@ -47,161 +49,25 @@ More screenshots are here: jedie.github.io/tree/master/screenshots/PyInventory
|
||||||
## Settings and upgrades
|
## Settings and upgrades
|
||||||
|
|
||||||
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
You can edit the file `/opt/yunohost/pyinventory/local_settings.py` to enable or disable features.
|
You can edit the file `/home/yunohost.app/django_example/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
Test sending emails:
|
Test sending emails, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh admin@yourdomain.tld
|
ssh admin@yourdomain.tld
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
root@yunohost:~# /home/yunohost.app/pyinventory/manage.py sendtestemail --admins
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
How to debug a django YunoHost app, take a look into:
|
||||||
To check current ADMINS run:
|
|
||||||
|
|
||||||
```bash
|
* https://github.com/YunoHost-Apps/django_example_ynh#developer-info
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
|
||||||
|
|
||||||
If you prefere to send error emails to a extrnal email address, just do something like this:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/pyinventory/local_settings.py
|
|
||||||
```
|
|
||||||
|
|
||||||
To check the effective settings, run this:
|
|
||||||
```bash
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py diffsettings
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
|
|
||||||
|
|
||||||
## SSO authentication
|
|
||||||
|
|
||||||
[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration):
|
|
||||||
|
|
||||||
* First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user
|
|
||||||
* All new users will be created as normal users
|
|
||||||
* Login via SSO is fully supported
|
|
||||||
* User Email, First / Last name will be updated from SSO data
|
|
||||||
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
* Report a bug about this package: https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
* Report a bug about PyInventory itself: https://github.com/jedie/PyInventory
|
|
||||||
* YunoHost website: https://yunohost.org/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Developer info
|
|
||||||
|
|
||||||
## package installation / debugging
|
|
||||||
|
|
||||||
Please send your pull request to https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
|
|
||||||
Try 'main' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Try 'testing' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
To remove call e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app remove pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Backup / remove / restore cycle, e.g.:
|
|
||||||
```bash
|
|
||||||
yunohost backup create --apps pyinventory
|
|
||||||
yunohost backup list
|
|
||||||
archives:
|
|
||||||
- pyinventory-pre-upgrade1
|
|
||||||
- 20201223-163434
|
|
||||||
yunohost app remove pyinventory
|
|
||||||
yunohost backup restore 20201223-163434 --apps pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Debug installation, e.g.:
|
|
||||||
```bash
|
|
||||||
root@yunohost:~# ls -la /var/www/pyinventory/
|
|
||||||
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/pyinventory/
|
|
||||||
total 58
|
|
||||||
drwxr-xr-x 5 pyinventory pyinventory 11 Dec 8 08:39 .
|
|
||||||
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 460 Dec 8 08:39 gunicorn.conf.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 0 Dec 8 08:39 local_settings.py
|
|
||||||
-rwxr-xr-x 1 pyinventory pyinventory 274 Dec 8 08:39 manage.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 171 Dec 8 08:39 secret.txt
|
|
||||||
drwxr-xr-x 6 pyinventory pyinventory 6 Dec 8 08:37 venv
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 115 Dec 8 08:39 wsgi.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 4737 Dec 8 08:39 settings.py
|
|
||||||
|
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py check
|
|
||||||
PyInventory v0.8.2 (Django v2.2.17)
|
|
||||||
DJANGO_SETTINGS_MODULE='settings'
|
|
||||||
PROJECT_PATH:/opt/yunohost/pyinventory/venv/lib/python3.7/site-packages
|
|
||||||
BASE_PATH:/opt/yunohost/pyinventory
|
|
||||||
System check identified no issues (0 silenced).
|
|
||||||
|
|
||||||
root@yunohost:~# tail -f /var/log/pyinventory/pyinventory.log
|
|
||||||
root@yunohost:~# cat /etc/systemd/system/pyinventory.service
|
|
||||||
|
|
||||||
root@yunohost:~# systemctl reload-or-restart pyinventory
|
|
||||||
root@yunohost:~# journalctl --unit=pyinventory --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
## local test
|
|
||||||
|
|
||||||
For quicker developing of PyInventory 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/pyinventory_ynh.git
|
|
||||||
~$ cd pyinventory_ynh/
|
|
||||||
~/pyinventory_ynh$ make
|
|
||||||
install-poetry install or update poetry
|
|
||||||
install install PyInventory via poetry
|
|
||||||
update update the sources and installation
|
|
||||||
local-test Run local_test.py to run pyinventory_ynh locally
|
|
||||||
~/pyinventory_ynh$ make install-poetry
|
|
||||||
~/pyinventory_ynh$ make install
|
|
||||||
~/pyinventory_ynh$ make local-test
|
|
||||||
```
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
* SQlite database will be used
|
|
||||||
* A super user with username `test` and password `test` is created
|
|
||||||
* The page is available under `http://127.0.0.1:8000/app_path/`
|
|
||||||
|
|
||||||
## Documentations et ressources
|
## Documentations et ressources
|
||||||
|
|
||||||
|
* Site officiel de l’app : <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* Documentation officielle utilisateur : <https://github.com/jedie/PyInventory>
|
* Documentation officielle utilisateur : <https://github.com/jedie/PyInventory>
|
||||||
* Documentation officielle de l’admin : <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
* Documentation officielle de l’admin : <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* Dépôt de code officiel de l’app : <https://github.com/jedie/PyInventory>
|
* Dépôt de code officiel de l’app : <https://github.com/YunoHost-Apps/pyinventory_ynh>
|
||||||
* YunoHost Store: <https://apps.yunohost.org/app/pyinventory>
|
* YunoHost Store: <https://apps.yunohost.org/app/pyinventory>
|
||||||
* Signaler un bug : <https://github.com/YunoHost-Apps/pyinventory_ynh/issues>
|
* Signaler un bug : <https://github.com/YunoHost-Apps/pyinventory_ynh/issues>
|
||||||
|
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
# See here for more information
|
|
||||||
# https://github.com/YunoHost/package_check#syntax-check_process-file
|
|
||||||
|
|
||||||
# Move this file from check_process.default to check_process when you have filled it.
|
|
||||||
|
|
||||||
;; Test complet
|
|
||||||
; Manifest
|
|
||||||
domain="domain.tld" (DOMAIN)
|
|
||||||
path="/path" (PATH)
|
|
||||||
admin="john" (USER)
|
|
||||||
is_public=1 (PUBLIC|public=1|private=0)
|
|
||||||
password="pass"
|
|
||||||
port="666" (PORT)
|
|
||||||
; Checks
|
|
||||||
pkg_linter=1
|
|
||||||
setup_sub_dir=1
|
|
||||||
setup_root=1
|
|
||||||
setup_nourl=0
|
|
||||||
setup_private=0
|
|
||||||
setup_public=1
|
|
||||||
upgrade=1
|
|
||||||
backup_restore=1
|
|
||||||
multi_instance=1
|
|
||||||
port_already_use=0
|
|
||||||
change_url=1
|
|
||||||
;;; Options
|
|
||||||
Email=
|
|
||||||
Notification=none
|
|
||||||
;;; Upgrade options
|
|
||||||
; commit=CommitHash
|
|
||||||
name=Name and date of the commit.
|
|
||||||
manifest_arg=domain=DOMAIN&path=PATH&admin=USER&language=fr&is_public=1&password=pass&port=666&
|
|
||||||
|
|
|
@ -17,4 +17,4 @@ accesslog = '__LOG_FILE__'
|
||||||
errorlog = '__LOG_FILE__'
|
errorlog = '__LOG_FILE__'
|
||||||
|
|
||||||
# https://docs.gunicorn.org/en/latest/settings.html#pidfile
|
# https://docs.gunicorn.org/en/latest/settings.html#pidfile
|
||||||
pidfile = '__FINALPATH__/gunicorn.pid'
|
pidfile = '__DATA_DIR__/gunicorn.pid' # /home/yunohost.app/$app/gunicorn.pid
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!__FINALPATH__/venv/bin/python
|
#!__DATA_DIR__/venv/bin/python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
location __PATH__/static/ {
|
location __PATH__/static/ {
|
||||||
# Service static files by nginx
|
# Service static files by nginx
|
||||||
# e.g.: /var/www/$app/static
|
# e.g.: /var/www/$app/static/
|
||||||
alias __PUBLIC_PATH__/static/;
|
alias __INSTALL_DIR__/static/;
|
||||||
expires 30d;
|
expires 30d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,255 +1,367 @@
|
||||||
asgiref==3.7.2 ; python_version >= "3.9" and python_version < "4" \
|
#
|
||||||
|
# This file is autogenerated by pip-compile with Python 3.11
|
||||||
|
# by the following command:
|
||||||
|
#
|
||||||
|
# ./dev-cli.py update
|
||||||
|
#
|
||||||
|
asgiref==3.7.2 \
|
||||||
--hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
|
--hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
|
||||||
--hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
|
--hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
|
||||||
async-timeout==4.0.3 ; python_version >= "3.9" and python_full_version <= "3.11.2" \
|
# via django
|
||||||
|
async-timeout==4.0.3 \
|
||||||
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
|
--hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \
|
||||||
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
|
--hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028
|
||||||
bleach==6.0.0 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory-ynh (pyproject.toml)
|
||||||
--hash=sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414 \
|
bleach==6.1.0 \
|
||||||
--hash=sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4
|
--hash=sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe \
|
||||||
bx-django-utils==63 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6
|
||||||
--hash=sha256:0023c0c18c8ce21fbee0e3bb563cd0283749495ca22cab1857ac971e4ee2bb05 \
|
# via django-tools
|
||||||
--hash=sha256:3b050d9d9d4e496e082c29d98d7633eb89ad028c658743b0032ee88e7e49be63
|
bx-django-utils==67 \
|
||||||
bx-py-utils==85 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:8740fdaf98ed68a8ddb3af025d9b4f87c99101405898ddca86810b0c384b215a \
|
||||||
--hash=sha256:8d6ee4bb0c431304b812f5bebb1bc8e2ab05f1b6c2f8d16d352cbcee5e916cd2 \
|
--hash=sha256:aca0ae5c91a62e4f594172b8c43468c701516f99ae50d99412d5299ba375df03
|
||||||
--hash=sha256:df023fa05cda8e969d2cbdb4cc348d8b7670567a2fe775faf7a0c869ec56eaa2
|
# via pyinventory
|
||||||
certifi==2023.7.22 ; python_version >= "3.9" and python_version < "4" \
|
bx-py-utils==88 \
|
||||||
|
--hash=sha256:32fbc7e9ff3dfb0a817c80fb1d165ec559643dab59c0be549e646acbf8223b75 \
|
||||||
|
--hash=sha256:3a6f4eeef6abcac834b2c1ea4c5211130fd930a064aa0baabddd7c2bd00e38ac
|
||||||
|
# via
|
||||||
|
# bx-django-utils
|
||||||
|
# cli-base-utilities
|
||||||
|
# django-tools
|
||||||
|
# pyinventory
|
||||||
|
certifi==2023.7.22 \
|
||||||
--hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
|
--hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
|
||||||
--hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
|
--hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
|
||||||
charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "4" \
|
# via requests
|
||||||
--hash=sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96 \
|
charset-normalizer==3.3.2 \
|
||||||
--hash=sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c \
|
--hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \
|
||||||
--hash=sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710 \
|
--hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \
|
||||||
--hash=sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706 \
|
--hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \
|
||||||
--hash=sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020 \
|
--hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \
|
||||||
--hash=sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252 \
|
--hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \
|
||||||
--hash=sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad \
|
--hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \
|
||||||
--hash=sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329 \
|
--hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \
|
||||||
--hash=sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a \
|
--hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \
|
||||||
--hash=sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f \
|
--hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \
|
||||||
--hash=sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6 \
|
--hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \
|
||||||
--hash=sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4 \
|
--hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \
|
||||||
--hash=sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a \
|
--hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \
|
||||||
--hash=sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46 \
|
--hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \
|
||||||
--hash=sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2 \
|
--hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \
|
||||||
--hash=sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23 \
|
--hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \
|
||||||
--hash=sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace \
|
--hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \
|
||||||
--hash=sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd \
|
--hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \
|
||||||
--hash=sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982 \
|
--hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \
|
||||||
--hash=sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10 \
|
--hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \
|
||||||
--hash=sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2 \
|
--hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \
|
||||||
--hash=sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea \
|
--hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \
|
||||||
--hash=sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09 \
|
--hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \
|
||||||
--hash=sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5 \
|
--hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \
|
||||||
--hash=sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149 \
|
--hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \
|
||||||
--hash=sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489 \
|
--hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \
|
||||||
--hash=sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9 \
|
--hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \
|
||||||
--hash=sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80 \
|
--hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \
|
||||||
--hash=sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592 \
|
--hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \
|
||||||
--hash=sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3 \
|
--hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \
|
||||||
--hash=sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6 \
|
--hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \
|
||||||
--hash=sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed \
|
--hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \
|
||||||
--hash=sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c \
|
--hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \
|
||||||
--hash=sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200 \
|
--hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \
|
||||||
--hash=sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a \
|
--hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \
|
||||||
--hash=sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e \
|
--hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \
|
||||||
--hash=sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d \
|
--hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \
|
||||||
--hash=sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6 \
|
--hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \
|
||||||
--hash=sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623 \
|
--hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \
|
||||||
--hash=sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669 \
|
--hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \
|
||||||
--hash=sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3 \
|
--hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \
|
||||||
--hash=sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa \
|
--hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \
|
||||||
--hash=sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9 \
|
--hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \
|
||||||
--hash=sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2 \
|
--hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \
|
||||||
--hash=sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f \
|
--hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \
|
||||||
--hash=sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1 \
|
--hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \
|
||||||
--hash=sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4 \
|
--hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \
|
||||||
--hash=sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a \
|
--hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \
|
||||||
--hash=sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8 \
|
--hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \
|
||||||
--hash=sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3 \
|
--hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \
|
||||||
--hash=sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029 \
|
--hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \
|
||||||
--hash=sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f \
|
--hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \
|
||||||
--hash=sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959 \
|
--hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \
|
||||||
--hash=sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22 \
|
--hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \
|
||||||
--hash=sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7 \
|
--hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \
|
||||||
--hash=sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952 \
|
--hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \
|
||||||
--hash=sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346 \
|
--hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \
|
||||||
--hash=sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e \
|
--hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \
|
||||||
--hash=sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d \
|
--hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \
|
||||||
--hash=sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299 \
|
--hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \
|
||||||
--hash=sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd \
|
--hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \
|
||||||
--hash=sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a \
|
--hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \
|
||||||
--hash=sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3 \
|
--hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \
|
||||||
--hash=sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037 \
|
--hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \
|
||||||
--hash=sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94 \
|
--hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \
|
||||||
--hash=sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c \
|
--hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \
|
||||||
--hash=sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858 \
|
--hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \
|
||||||
--hash=sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a \
|
--hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \
|
||||||
--hash=sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449 \
|
--hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \
|
||||||
--hash=sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c \
|
--hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \
|
||||||
--hash=sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918 \
|
--hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \
|
||||||
--hash=sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1 \
|
--hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \
|
||||||
--hash=sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c \
|
--hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \
|
||||||
--hash=sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac \
|
--hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \
|
||||||
--hash=sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa
|
--hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \
|
||||||
colorama==0.4.6 ; python_version >= "3.9" and python_version < "4" and sys_platform == "win32" \
|
--hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \
|
||||||
--hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \
|
--hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \
|
||||||
--hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6
|
--hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \
|
||||||
colorlog==6.7.0 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \
|
||||||
|
--hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \
|
||||||
|
--hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \
|
||||||
|
--hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \
|
||||||
|
--hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \
|
||||||
|
--hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \
|
||||||
|
--hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \
|
||||||
|
--hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \
|
||||||
|
--hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \
|
||||||
|
--hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \
|
||||||
|
--hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \
|
||||||
|
--hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \
|
||||||
|
--hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561
|
||||||
|
# via requests
|
||||||
|
cli-base-utilities==0.4.4 \
|
||||||
|
--hash=sha256:110bef895fb7dfc29662f463ccedc4c985a880afbde2e6dea387d0d2f96f4985 \
|
||||||
|
--hash=sha256:72d4248776519a21c3448d6e348511ce6fe8c3742c154e158473236c8278fb1c
|
||||||
|
# via pyinventory-ynh (pyproject.toml)
|
||||||
|
click==8.1.7 \
|
||||||
|
--hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \
|
||||||
|
--hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de
|
||||||
|
# via
|
||||||
|
# cli-base-utilities
|
||||||
|
# rich-click
|
||||||
|
colorlog==6.7.0 \
|
||||||
--hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \
|
--hash=sha256:0d33ca236784a1ba3ff9c532d4964126d8a2c44f1f0cb1d2b0728196f512f662 \
|
||||||
--hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5
|
--hash=sha256:bd94bd21c1e13fac7bd3153f4bc3a7dc0eb0974b8bc2fdf1a989e474f6e582e5
|
||||||
defusedxml==0.7.1 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
|
# django-yunohost-integration
|
||||||
|
# pyinventory
|
||||||
|
defusedxml==0.7.1 \
|
||||||
--hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \
|
--hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \
|
||||||
--hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61
|
--hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61
|
||||||
diff-match-patch==20230430 ; python_version >= "3.9" and python_version < "4" \
|
# via odfpy
|
||||||
|
diff-match-patch==20230430 \
|
||||||
--hash=sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c \
|
--hash=sha256:953019cdb9c9d2c9e47b5b12bcff3cf4746fc4598eb406076fa1fc27e6a1f15c \
|
||||||
--hash=sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93
|
--hash=sha256:dce43505fb7b1b317de7195579388df0746d90db07015ed47a85e5e44930ef93
|
||||||
django-admin-sortable2==2.1.9 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
--hash=sha256:6de19689cb2f131d256ce19d2fd148728d551943d8463b1d81f6334adfa0b6fc \
|
# django-import-export
|
||||||
--hash=sha256:bf036785c598685a0019eb08340b88fe6ca74bd178033e2290e6c41b62fa4bf1
|
# django-reversion-compare
|
||||||
django-axes==6.1.0 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
django==4.2.7 \
|
||||||
--hash=sha256:a7d509dc76e67440839522a182dc63ecafc3bac3af9de6f263d2bcec1154e50e \
|
--hash=sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41 \
|
||||||
--hash=sha256:e3d44d4ec64ba6d470ef01b6c4b53b6b3747de96821f7c0ef96c64bffa9f6f74
|
--hash=sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9
|
||||||
django-ckeditor==6.7.0 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
|
# bx-django-utils
|
||||||
|
# django-admin-sortable2
|
||||||
|
# django-axes
|
||||||
|
# django-ckeditor
|
||||||
|
# django-dbbackup
|
||||||
|
# django-debug-toolbar
|
||||||
|
# django-import-export
|
||||||
|
# django-js-asset
|
||||||
|
# django-redis
|
||||||
|
# django-reversion
|
||||||
|
# django-reversion-compare
|
||||||
|
# django-tagulous
|
||||||
|
# django-tools
|
||||||
|
# django-yunohost-integration
|
||||||
|
# pyinventory
|
||||||
|
django-admin-sortable2==2.1.10 \
|
||||||
|
--hash=sha256:3756b02c7d09c5b37efe657718d5aae2b75f46fd01bbfe1c39d4e60651019d79 \
|
||||||
|
--hash=sha256:98d1c8d268398c3c3aff4752f766b2c307a5bd97174938c29f818d8a4697854d
|
||||||
|
# via pyinventory
|
||||||
|
django-axes==6.1.1 \
|
||||||
|
--hash=sha256:29c48ff5f09046afd5e9a16e96d3bbb79f6c11c59f0a7bbd732559e60d0aa9fa \
|
||||||
|
--hash=sha256:cd1bc4f7becc8e9243eb4090dffa258d7d7125ca0ce3153b6ffc920bccbf2c3f
|
||||||
|
# via django-yunohost-integration
|
||||||
|
django-ckeditor==6.7.0 \
|
||||||
--hash=sha256:0489f7a6ae93360d328f77cea17c04891103cbdfa6c962af386bbe47e811671b \
|
--hash=sha256:0489f7a6ae93360d328f77cea17c04891103cbdfa6c962af386bbe47e811671b \
|
||||||
--hash=sha256:73399fb8f56f565e7519b57adbd7c585623db2cdc8c75666f56918d3eecf7906
|
--hash=sha256:73399fb8f56f565e7519b57adbd7c585623db2cdc8c75666f56918d3eecf7906
|
||||||
django-dbbackup==4.0.2 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory
|
||||||
|
django-dbbackup==4.0.2 \
|
||||||
--hash=sha256:1874d684abc22260972a67668a6db3331b24d7e1e8af89eaffdcd61eb27dbc2a \
|
--hash=sha256:1874d684abc22260972a67668a6db3331b24d7e1e8af89eaffdcd61eb27dbc2a \
|
||||||
--hash=sha256:3ccde831f1a8268fb031b37a8e7e2de3abb556623023af1e859cd7104c09ea2a
|
--hash=sha256:3ccde831f1a8268fb031b37a8e7e2de3abb556623023af1e859cd7104c09ea2a
|
||||||
django-debug-toolbar==4.2.0 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory
|
||||||
|
django-debug-toolbar==4.2.0 \
|
||||||
--hash=sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327 \
|
--hash=sha256:af99128c06e8e794479e65ab62cc6c7d1e74e1c19beb44dcbf9bad7a9c017327 \
|
||||||
--hash=sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc
|
--hash=sha256:bc7fdaafafcdedefcc67a4a5ad9dac96efd6e41db15bc74d402a54a2ba4854dc
|
||||||
django-import-export==3.2.0 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory
|
||||||
--hash=sha256:1d3f2cb2ee3cca0386ed60651fa1623be989f130d9fbdf98a67f7dc3a94b8a37 \
|
django-import-export==3.3.2 \
|
||||||
--hash=sha256:38fd7b9439b9e3aa1a4747421c1087a5bc194e915a28d795fb8429a5f8028f2d
|
--hash=sha256:9a5c7c191014e4defb01573ee94864b60724a203f1b8a7e5e67a03f06b27b62d \
|
||||||
django-js-asset==2.1.0 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:d13e7508190f46442280bd7d04efcf49af6521350a70a6f9e06447ef28d6a41d
|
||||||
|
# via pyinventory
|
||||||
|
django-js-asset==2.1.0 \
|
||||||
--hash=sha256:36a3a4dd6e9efc895fb127d13126020f6ec1ec9469ad42878d42143f22495d90 \
|
--hash=sha256:36a3a4dd6e9efc895fb127d13126020f6ec1ec9469ad42878d42143f22495d90 \
|
||||||
--hash=sha256:be6f69ae5c4865617aa7726c48eddb64089a1e7d4ea7d22a35a3beb8282020f6
|
--hash=sha256:be6f69ae5c4865617aa7726c48eddb64089a1e7d4ea7d22a35a3beb8282020f6
|
||||||
django-redis==5.3.0 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
# via django-ckeditor
|
||||||
--hash=sha256:2d8660d39f586c41c9907d5395693c477434141690fd7eca9d32376af00b0aac \
|
django-redis==5.4.0 \
|
||||||
--hash=sha256:8bc5793ec06b28ea802aad85ec437e7646511d4e571e07ccad19cfed8b9ddd44
|
--hash=sha256:6a02abaa34b0fea8bf9b707d2c363ab6adc7409950b2db93602e6cb292818c42 \
|
||||||
django-reversion-compare==0.16.2 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:ebc88df7da810732e2af9987f7f426c96204bf89319df4c6da6ca9a2942edd5b
|
||||||
|
# via django-yunohost-integration
|
||||||
|
django-reversion==5.0.8 \
|
||||||
|
--hash=sha256:229ad0d2819416157502ff13d81bad2366227b763ce85b63b8a223edb756a513 \
|
||||||
|
--hash=sha256:45d378bc6e606df6b2ad0077aec8b0a00e35f18c74ca2a1ae9cc262ceb32fb9a
|
||||||
|
# via django-reversion-compare
|
||||||
|
django-reversion-compare==0.16.2 \
|
||||||
--hash=sha256:5629f226fc73bd7b95de47b2e21e2eba2fa39f004ba0fee6d460e96676c0dc9b \
|
--hash=sha256:5629f226fc73bd7b95de47b2e21e2eba2fa39f004ba0fee6d460e96676c0dc9b \
|
||||||
--hash=sha256:9d7d096534f5d0e49d7419a8a29b4517580e6a7855529e594d10bfb373f980ab
|
--hash=sha256:9d7d096534f5d0e49d7419a8a29b4517580e6a7855529e594d10bfb373f980ab
|
||||||
django-reversion==5.0.4 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory
|
||||||
--hash=sha256:a591cbce8621b5d036a37617554668b5ef2eb9777682e3af20b6401ee87cfbc5 \
|
django-tagulous==1.3.3 \
|
||||||
--hash=sha256:c12bab452d31dd3c244456cf1df383acf14ba147cf99404c5e44412596de42fc
|
|
||||||
django-tagulous==1.3.3 ; python_version >= "3.9" and python_version < "4" \
|
|
||||||
--hash=sha256:ad3bb85f4cce83a47e4c0257143229cb92a294defa02fe661823b0442b35d478 \
|
--hash=sha256:ad3bb85f4cce83a47e4c0257143229cb92a294defa02fe661823b0442b35d478 \
|
||||||
--hash=sha256:d445590ae1b5cb9b8c5a425f97bf5f01148a33419c19edeb721ebd9fdd6792fe
|
--hash=sha256:d445590ae1b5cb9b8c5a425f97bf5f01148a33419c19edeb721ebd9fdd6792fe
|
||||||
django-tools==0.54.0 ; python_version >= "3.9" and python_version < "4" \
|
# via pyinventory
|
||||||
|
django-tools==0.54.0 \
|
||||||
--hash=sha256:5040a91282be9d1c9d379b0c65da50bcb3691bff03cee54fd4123ace238c3a43 \
|
--hash=sha256:5040a91282be9d1c9d379b0c65da50bcb3691bff03cee54fd4123ace238c3a43 \
|
||||||
--hash=sha256:a7b7bfa5b9c5a81966454d17dffb2403cee25a806c858ee0486a08798227598f
|
--hash=sha256:a7b7bfa5b9c5a81966454d17dffb2403cee25a806c858ee0486a08798227598f
|
||||||
django-yunohost-integration[ynh]==0.5.2 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
# via
|
||||||
--hash=sha256:05d96ae0689eb1b8c7bc30e0d247fddb1c18d2845c17a6e4ca533ed47731a4cb \
|
# django-yunohost-integration
|
||||||
--hash=sha256:6689115f88dc84acaf94dc01ce940023f566bf933f57115563120912a14cbeff
|
# pyinventory
|
||||||
django==4.1.10 ; python_version >= "3.9" and python_version < "4" \
|
django-yunohost-integration[ynh]==0.6.0 \
|
||||||
--hash=sha256:26d0260c2fb8121009e62ffc548b2398dea2522b6454208a852fb0ef264c206c \
|
--hash=sha256:9596ab56b66edf1b56eccaceb4b5807df237e752128e79568cd13b075267f26f \
|
||||||
--hash=sha256:56343019a9fd839e2e5bf203daf45f25af79d5bffa4c71d56eae4f4404d82ade
|
--hash=sha256:dfb72b94ae30e02948dd60ca76d56da4ca6a74ea04f357b8d61b94807fca0493
|
||||||
et-xmlfile==1.1.0 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
|
# django-yunohost-integration
|
||||||
|
# pyinventory-ynh (pyproject.toml)
|
||||||
|
et-xmlfile==1.1.0 \
|
||||||
--hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c \
|
--hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c \
|
||||||
--hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada
|
--hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada
|
||||||
gunicorn==21.2.0 ; python_version >= "3.9" and python_version < "4" \
|
# via openpyxl
|
||||||
|
gunicorn==21.2.0 \
|
||||||
--hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \
|
--hash=sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0 \
|
||||||
--hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033
|
--hash=sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033
|
||||||
icdiff==2.0.6 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
--hash=sha256:a2673b335d671e64fc73c44e1eaa0aa01fd0e68354e58ee17e863ab29912a79a
|
# django-yunohost-integration
|
||||||
idna==3.4 ; python_version >= "3.9" and python_version < "4" \
|
# pyinventory
|
||||||
|
icdiff==2.0.7 \
|
||||||
|
--hash=sha256:f05d1b3623223dd1c70f7848da7d699de3d9a2550b902a8234d9026292fb5762 \
|
||||||
|
--hash=sha256:f79a318891adbf59a45e3a7694f5e1f18c5407065264637072ac8363b759866f
|
||||||
|
# via django-tools
|
||||||
|
idna==3.4 \
|
||||||
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
|
--hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
|
||||||
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
|
--hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
|
||||||
markuppy==1.14 ; python_version >= "3.9" and python_version < "4" \
|
# via requests
|
||||||
|
markdown-it-py==3.0.0 \
|
||||||
|
--hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
|
||||||
|
--hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
|
||||||
|
# via rich
|
||||||
|
markuppy==1.14 \
|
||||||
--hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f
|
--hash=sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f
|
||||||
odfpy==1.4.1 ; python_version >= "3.9" and python_version < "4" \
|
# via tablib
|
||||||
|
mdurl==0.1.2 \
|
||||||
|
--hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
|
||||||
|
--hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
|
||||||
|
# via markdown-it-py
|
||||||
|
odfpy==1.4.1 \
|
||||||
--hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec
|
--hash=sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec
|
||||||
openpyxl==3.1.2 ; python_version >= "3.9" and python_version < "4" \
|
# via tablib
|
||||||
|
openpyxl==3.1.2 \
|
||||||
--hash=sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184 \
|
--hash=sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184 \
|
||||||
--hash=sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5
|
--hash=sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5
|
||||||
packaging==23.1 ; python_version >= "3.9" and python_version < "4" \
|
# via tablib
|
||||||
--hash=sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61 \
|
packaging==23.2 \
|
||||||
--hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f
|
--hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
|
||||||
pillow==10.0.0 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
|
||||||
--hash=sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5 \
|
# via
|
||||||
--hash=sha256:040586f7d37b34547153fa383f7f9aed68b738992380ac911447bb78f2abe530 \
|
# django-yunohost-integration
|
||||||
--hash=sha256:0b6eb5502f45a60a3f411c63187db83a3d3107887ad0d036c13ce836f8a36f1d \
|
# gunicorn
|
||||||
--hash=sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca \
|
pillow==10.1.0 \
|
||||||
--hash=sha256:1f62406a884ae75fb2f818694469519fb685cc7eaff05d3451a9ebe55c646891 \
|
--hash=sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d \
|
||||||
--hash=sha256:22c10cc517668d44b211717fd9775799ccec4124b9a7f7b3635fc5386e584992 \
|
--hash=sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de \
|
||||||
--hash=sha256:3400aae60685b06bb96f99a21e1ada7bc7a413d5f49bce739828ecd9391bb8f7 \
|
--hash=sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616 \
|
||||||
--hash=sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3 \
|
--hash=sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839 \
|
||||||
--hash=sha256:368ab3dfb5f49e312231b6f27b8820c823652b7cd29cfbd34090565a015e99ba \
|
--hash=sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099 \
|
||||||
--hash=sha256:38250a349b6b390ee6047a62c086d3817ac69022c127f8a5dc058c31ccef17f3 \
|
--hash=sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a \
|
||||||
--hash=sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3 \
|
--hash=sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219 \
|
||||||
--hash=sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f \
|
--hash=sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106 \
|
||||||
--hash=sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538 \
|
--hash=sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b \
|
||||||
--hash=sha256:3ed64f9ca2f0a95411e88a4efbd7a29e5ce2cea36072c53dd9d26d9c76f753b3 \
|
--hash=sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412 \
|
||||||
--hash=sha256:3f07ea8d2f827d7d2a49ecf1639ec02d75ffd1b88dcc5b3a61bbb37a8759ad8d \
|
--hash=sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b \
|
||||||
--hash=sha256:520f2a520dc040512699f20fa1c363eed506e94248d71f85412b625026f6142c \
|
--hash=sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7 \
|
||||||
--hash=sha256:5c6e3df6bdd396749bafd45314871b3d0af81ff935b2d188385e970052091017 \
|
--hash=sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2 \
|
||||||
--hash=sha256:608bfdee0d57cf297d32bcbb3c728dc1da0907519d1784962c5f0c68bb93e5a3 \
|
--hash=sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7 \
|
||||||
--hash=sha256:685ac03cc4ed5ebc15ad5c23bc555d68a87777586d970c2c3e216619a5476223 \
|
--hash=sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14 \
|
||||||
--hash=sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e \
|
--hash=sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f \
|
||||||
--hash=sha256:76edb0a1fa2b4745fb0c99fb9fb98f8b180a1bbceb8be49b087e0b21867e77d3 \
|
--hash=sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27 \
|
||||||
--hash=sha256:7be600823e4c8631b74e4a0d38384c73f680e6105a7d3c6824fcf226c178c7e6 \
|
--hash=sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57 \
|
||||||
--hash=sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640 \
|
--hash=sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262 \
|
||||||
--hash=sha256:88af2003543cc40c80f6fca01411892ec52b11021b3dc22ec3bc9d5afd1c5334 \
|
--hash=sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28 \
|
||||||
--hash=sha256:8c11160913e3dd06c8ffdb5f233a4f254cb449f4dfc0f8f4549eda9e542c93d1 \
|
--hash=sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610 \
|
||||||
--hash=sha256:8f8182b523b2289f7c415f589118228d30ac8c355baa2f3194ced084dac2dbba \
|
--hash=sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172 \
|
||||||
--hash=sha256:9211e7ad69d7c9401cfc0e23d49b69ca65ddd898976d660a2fa5904e3d7a9baa \
|
--hash=sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273 \
|
||||||
--hash=sha256:92be919bbc9f7d09f7ae343c38f5bb21c973d2576c1d45600fce4b74bafa7ac0 \
|
--hash=sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e \
|
||||||
--hash=sha256:9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396 \
|
--hash=sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d \
|
||||||
--hash=sha256:9f7c16705f44e0504a3a2a14197c1f0b32a95731d251777dcb060aa83022cb2d \
|
--hash=sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818 \
|
||||||
--hash=sha256:9fb218c8a12e51d7ead2a7c9e101a04982237d4855716af2e9499306728fb485 \
|
--hash=sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f \
|
||||||
--hash=sha256:a74ba0c356aaa3bb8e3eb79606a87669e7ec6444be352870623025d75a14a2bf \
|
--hash=sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9 \
|
||||||
--hash=sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43 \
|
--hash=sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01 \
|
||||||
--hash=sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37 \
|
--hash=sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7 \
|
||||||
--hash=sha256:c189af0545965fa8d3b9613cfdb0cd37f9d71349e0f7750e1fd704648d475ed2 \
|
--hash=sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651 \
|
||||||
--hash=sha256:c1fbe7621c167ecaa38ad29643d77a9ce7311583761abf7836e1510c580bf3dd \
|
--hash=sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312 \
|
||||||
--hash=sha256:c7cf14a27b0d6adfaebb3ae4153f1e516df54e47e42dcc073d7b3d76111a8d86 \
|
--hash=sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80 \
|
||||||
--hash=sha256:c9f72a021fbb792ce98306ffb0c348b3c9cb967dce0f12a49aa4c3d3fdefa967 \
|
--hash=sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666 \
|
||||||
--hash=sha256:cd25d2a9d2b36fcb318882481367956d2cf91329f6892fe5d385c346c0649629 \
|
--hash=sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061 \
|
||||||
--hash=sha256:ce543ed15570eedbb85df19b0a1a7314a9c8141a36ce089c0a894adbfccb4568 \
|
--hash=sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b \
|
||||||
--hash=sha256:ce7b031a6fc11365970e6a5686d7ba8c63e4c1cf1ea143811acbb524295eabed \
|
--hash=sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992 \
|
||||||
--hash=sha256:d35e3c8d9b1268cbf5d3670285feb3528f6680420eafe35cccc686b73c1e330f \
|
--hash=sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593 \
|
||||||
--hash=sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551 \
|
--hash=sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4 \
|
||||||
--hash=sha256:d5d0dae4cfd56969d23d94dc8e89fb6a217be461c69090768227beb8ed28c0a3 \
|
--hash=sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db \
|
||||||
--hash=sha256:d5db32e2a6ccbb3d34d87c87b432959e0db29755727afb37290e10f6e8e62614 \
|
--hash=sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba \
|
||||||
--hash=sha256:d72e2ecc68a942e8cf9739619b7f408cc7b272b279b56b2c83c6123fcfa5cdff \
|
--hash=sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd \
|
||||||
--hash=sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d \
|
--hash=sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e \
|
||||||
--hash=sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883 \
|
--hash=sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212 \
|
||||||
--hash=sha256:db24668940f82321e746773a4bc617bfac06ec831e5c88b643f91f122a785684 \
|
--hash=sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb \
|
||||||
--hash=sha256:dbc02381779d412145331789b40cc7b11fdf449e5d94f6bc0b080db0a56ea3f0 \
|
--hash=sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2 \
|
||||||
--hash=sha256:dffe31a7f47b603318c609f378ebcd57f1554a3a6a8effbc59c3c69f804296de \
|
--hash=sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34 \
|
||||||
--hash=sha256:edf4392b77bdc81f36e92d3a07a5cd072f90253197f4a52a55a8cec48a12483b \
|
--hash=sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256 \
|
||||||
--hash=sha256:efe8c0681042536e0d06c11f48cebe759707c9e9abf880ee213541c5b46c5bf3 \
|
--hash=sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f \
|
||||||
--hash=sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199 \
|
--hash=sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2 \
|
||||||
--hash=sha256:f88a0b92277de8e3ca715a0d79d68dc82807457dae3ab8699c758f07c20b3c51 \
|
--hash=sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38 \
|
||||||
--hash=sha256:faaf07ea35355b01a35cb442dd950d8f1bb5b040a7787791a535de13db15ed90
|
--hash=sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996 \
|
||||||
pprintpp==0.4.0 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a \
|
||||||
|
--hash=sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793
|
||||||
|
# via pyinventory
|
||||||
|
pprintpp==0.4.0 \
|
||||||
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
|
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
|
||||||
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
|
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
|
||||||
psycopg2==2.9.7 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
# via django-tools
|
||||||
--hash=sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084 \
|
psycopg2==2.9.9 \
|
||||||
--hash=sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1 \
|
--hash=sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981 \
|
||||||
--hash=sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866 \
|
--hash=sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516 \
|
||||||
--hash=sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9 \
|
--hash=sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3 \
|
||||||
--hash=sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5 \
|
--hash=sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa \
|
||||||
--hash=sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723 \
|
--hash=sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a \
|
||||||
--hash=sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5 \
|
--hash=sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693 \
|
||||||
--hash=sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2 \
|
--hash=sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372 \
|
||||||
--hash=sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2 \
|
--hash=sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e \
|
||||||
--hash=sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8 \
|
--hash=sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59 \
|
||||||
--hash=sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8
|
--hash=sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156 \
|
||||||
pyinventory==0.19.2 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024 \
|
||||||
--hash=sha256:06424c8ddf8521cf5806d834e3aede8254a4960f538a210bfd88508d88fb1d36 \
|
--hash=sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913 \
|
||||||
--hash=sha256:2d92a7f4b4a7b3191819f671e95070b3dd8844fdf2ceb8d971da1e61b094db24
|
--hash=sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c
|
||||||
python-stdnum==1.18 ; python_version >= "3.9" and python_version < "4" \
|
# via django-yunohost-integration
|
||||||
--hash=sha256:bcc763d9c49ae23da5d2b7a686d5fd1deec9d9051341160a10d1ac723a26bec0 \
|
pygments==2.16.1 \
|
||||||
--hash=sha256:d7f2a3c7ef4635c957b9cbdd9b1993d1f6ee3a2959f03e172c45440d99f296eb
|
--hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
|
||||||
pytz==2023.3 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
|
||||||
--hash=sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588 \
|
# via rich
|
||||||
--hash=sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb
|
pyinventory==0.19.3 \
|
||||||
pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:42e5710956e466df389ddf01c1ab8f9c432890b745a2a32765085c67fda78cfa \
|
||||||
|
--hash=sha256:b9efc88ca43aa57c4e04f2024087e50015bd9fc969730e3049258b06d048cce4
|
||||||
|
# via pyinventory-ynh (pyproject.toml)
|
||||||
|
python-stdnum==1.19 \
|
||||||
|
--hash=sha256:133ec82f56390ea74c190569e98f2fb14b869808b1d54785708f22d0fead8b3f \
|
||||||
|
--hash=sha256:1b5b401ad3f45b798b0317313b781a433f5d7a5ff2c9feb8054664f76f78644e
|
||||||
|
# via bx-django-utils
|
||||||
|
pytz==2023.3.post1 \
|
||||||
|
--hash=sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b \
|
||||||
|
--hash=sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7
|
||||||
|
# via django-dbbackup
|
||||||
|
pyyaml==6.0.1 \
|
||||||
|
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
|
||||||
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
|
--hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \
|
||||||
|
--hash=sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df \
|
||||||
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
|
--hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \
|
||||||
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
|
--hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \
|
||||||
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
|
--hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \
|
||||||
|
@ -257,7 +369,10 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
|
||||||
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
|
--hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \
|
||||||
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
|
--hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \
|
||||||
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
|
--hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \
|
||||||
|
--hash=sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290 \
|
||||||
|
--hash=sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9 \
|
||||||
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
|
--hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \
|
||||||
|
--hash=sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6 \
|
||||||
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
|
--hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \
|
||||||
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
|
--hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \
|
||||||
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
|
--hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \
|
||||||
|
@ -265,9 +380,12 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
|
||||||
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
|
--hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \
|
||||||
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
|
--hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \
|
||||||
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
|
--hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \
|
||||||
|
--hash=sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0 \
|
||||||
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
|
--hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \
|
||||||
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
|
--hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \
|
||||||
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
|
--hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \
|
||||||
|
--hash=sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28 \
|
||||||
|
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||||
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
||||||
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
||||||
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
||||||
|
@ -282,46 +400,79 @@ pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "4" \
|
||||||
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
|
--hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \
|
||||||
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
|
--hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \
|
||||||
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
|
--hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \
|
||||||
|
--hash=sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54 \
|
||||||
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
|
--hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \
|
||||||
|
--hash=sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b \
|
||||||
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
|
--hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \
|
||||||
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
|
--hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \
|
||||||
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
|
--hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \
|
||||||
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
|
--hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \
|
||||||
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
|
--hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \
|
||||||
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
|
--hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f
|
||||||
redis==5.0.0 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
# via
|
||||||
--hash=sha256:06570d0b2d84d46c21defc550afbaada381af82f5b83e5b3777600e05d8e2ed0 \
|
# django-yunohost-integration
|
||||||
--hash=sha256:5cea6c0d335c9a7332a460ed8729ceabb4d0c489c7285b0a86dbbf8a017bd120
|
# tablib
|
||||||
requests==2.31.0 ; python_version >= "3.9" and python_version < "4" \
|
redis==5.0.1 \
|
||||||
|
--hash=sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f \
|
||||||
|
--hash=sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f
|
||||||
|
# via django-redis
|
||||||
|
requests==2.31.0 \
|
||||||
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
--hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
|
||||||
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
--hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
|
||||||
setuptools==68.1.0 ; python_version >= "3.9" and python_full_version < "4.0.0" \
|
# via pyinventory
|
||||||
--hash=sha256:d59c97e7b774979a5ccb96388efc9eb65518004537e85d52e81eaee89ab6dd91 \
|
rich==13.6.0 \
|
||||||
--hash=sha256:e13e1b0bc760e9b0127eda042845999b2f913e12437046e663b833aa96d89715
|
--hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \
|
||||||
six==1.16.0 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef
|
||||||
|
# via
|
||||||
|
# cli-base-utilities
|
||||||
|
# rich-click
|
||||||
|
rich-click==1.7.1 \
|
||||||
|
--hash=sha256:660c8ea345343f47c5de88f62afa34a19d9f4c7accdd9c6e39dc17eece6affcd \
|
||||||
|
--hash=sha256:c37d19af85c86b9a256c18e9d23637ae89478300ec8dc5e220c6ca213675f2f9
|
||||||
|
# via cli-base-utilities
|
||||||
|
six==1.16.0 \
|
||||||
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
||||||
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
|
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
|
||||||
sqlparse==0.4.4 ; python_version >= "3.9" and python_version < "4" \
|
# via bleach
|
||||||
|
sqlparse==0.4.4 \
|
||||||
--hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
|
--hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
|
||||||
--hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
|
--hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
|
||||||
tablib[html,ods,xls,xlsx,yaml]==3.5.0 ; python_version >= "3.9" and python_version < "4" \
|
# via
|
||||||
|
# django
|
||||||
|
# django-debug-toolbar
|
||||||
|
tablib[html,ods,xls,xlsx,yaml]==3.5.0 \
|
||||||
--hash=sha256:9821caa9eca6062ff7299fa645e737aecff982e6b2b42046928a6413c8dabfd9 \
|
--hash=sha256:9821caa9eca6062ff7299fa645e737aecff982e6b2b42046928a6413c8dabfd9 \
|
||||||
--hash=sha256:f6661dfc45e1d4f51fa8a6239f9c8349380859a5bfaa73280645f046d6c96e33
|
--hash=sha256:f6661dfc45e1d4f51fa8a6239f9c8349380859a5bfaa73280645f046d6c96e33
|
||||||
typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.11" \
|
# via
|
||||||
--hash=sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36 \
|
# django-import-export
|
||||||
--hash=sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2
|
# tablib
|
||||||
tzdata==2023.3 ; python_version >= "3.9" and python_version < "4" and sys_platform == "win32" \
|
tomlkit==0.12.2 \
|
||||||
--hash=sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a \
|
--hash=sha256:df32fab589a81f0d7dc525a4267b6d7a64ee99619cbd1eeb0fae32c1dd426977 \
|
||||||
--hash=sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda
|
--hash=sha256:eeea7ac7563faeab0a1ed8fe12c2e5a51c61f933f2502f7e9db0241a65163ad0
|
||||||
urllib3==2.0.4 ; python_version >= "3.9" and python_version < "4" \
|
# via cli-base-utilities
|
||||||
--hash=sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11 \
|
typing-extensions==4.8.0 \
|
||||||
--hash=sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4
|
--hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
|
||||||
webencodings==0.5.1 ; python_version >= "3.9" and python_version < "4" \
|
--hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
|
||||||
|
# via rich-click
|
||||||
|
urllib3==2.0.7 \
|
||||||
|
--hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \
|
||||||
|
--hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e
|
||||||
|
# via requests
|
||||||
|
webencodings==0.5.1 \
|
||||||
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
||||||
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
|
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
|
||||||
xlrd==2.0.1 ; python_version >= "3.9" and python_version < "4" \
|
# via bleach
|
||||||
|
xlrd==2.0.1 \
|
||||||
--hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \
|
--hash=sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd \
|
||||||
--hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88
|
--hash=sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88
|
||||||
xlwt==1.3.0 ; python_version >= "3.9" and python_version < "4" \
|
# via tablib
|
||||||
|
xlwt==1.3.0 \
|
||||||
--hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \
|
--hash=sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e \
|
||||||
--hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88
|
--hash=sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88
|
||||||
|
# via tablib
|
||||||
|
|
||||||
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
|
setuptools==68.2.2 \
|
||||||
|
--hash=sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87 \
|
||||||
|
--hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
|
||||||
|
# via django-axes
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Please do not modify this file, it will be reset at the next update.
|
# Please do not modify this file, it will be reset at the next update.
|
||||||
# You can edit the file __FINALPATH__/local_settings.py and add/modify the settings you need.
|
# You can edit the file __DATA_DIR__/local_settings.py and add/modify the settings you need.
|
||||||
# The parameters you add in local_settings.py will overwrite these,
|
# 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.
|
# but you can use the options and documentation in this file to find out what can be done.
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ from inventory_project.settings.prod import * # noqa:F401,F403 isort:skip
|
||||||
from django_yunohost_integration.base_settings import LOGGING # noqa:F401 isort:skip
|
from django_yunohost_integration.base_settings import LOGGING # noqa:F401 isort:skip
|
||||||
|
|
||||||
|
|
||||||
FINALPATH = __Path('__FINALPATH__') # /opt/yunohost/$app
|
DATA_DIR_PATH = __Path('__DATA_DIR__') # /home/yunohost.app/$app/
|
||||||
assert FINALPATH.is_dir(), f'Directory not exists: {FINALPATH}'
|
assert DATA_DIR_PATH.is_dir(), f'Directory not exists: {DATA_DIR_PATH}'
|
||||||
|
|
||||||
PUBLIC_PATH = __Path('__PUBLIC_PATH__') # /var/www/$app
|
INSTALL_DIR_PATH = __Path('__INSTALL_DIR__') # /var/www/$app/
|
||||||
assert PUBLIC_PATH.is_dir(), f'Directory not exists: {PUBLIC_PATH}'
|
assert INSTALL_DIR_PATH.is_dir(), f'Directory not exists: {INSTALL_DIR_PATH}'
|
||||||
|
|
||||||
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/pyinventory_ynh.log
|
LOG_FILE_PATH = __Path('__LOG_FILE__') # /var/log/$app/pyinventory_ynh.log
|
||||||
assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}'
|
assert LOG_FILE_PATH.is_file(), f'File not exists: {LOG_FILE_PATH}'
|
||||||
|
|
||||||
PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH
|
PATH_URL = '__PATH__'
|
||||||
PATH_URL = PATH_URL.strip('/')
|
PATH_URL = PATH_URL.strip('/')
|
||||||
|
|
||||||
YNH_CURRENT_HOST = '__YNH_CURRENT_HOST__' # YunoHost main domain from: /etc/yunohost/current_host
|
YNH_CURRENT_HOST = '__YNH_CURRENT_HOST__' # YunoHost main domain from: /etc/yunohost/current_host
|
||||||
|
@ -40,7 +40,7 @@ YNH_CURRENT_HOST = '__YNH_CURRENT_HOST__' # YunoHost main domain from: /etc/yun
|
||||||
# config_panel.toml settings:
|
# config_panel.toml settings:
|
||||||
|
|
||||||
DEBUG_ENABLED = '__DEBUG_ENABLED__'
|
DEBUG_ENABLED = '__DEBUG_ENABLED__'
|
||||||
DEBUG = bool(int(DEBUG_ENABLED))
|
DEBUG = DEBUG_ENABLED == 'YES'
|
||||||
|
|
||||||
LOG_LEVEL = '__LOG_LEVEL__'
|
LOG_LEVEL = '__LOG_LEVEL__'
|
||||||
ADMIN_EMAIL = '__ADMIN_EMAIL__'
|
ADMIN_EMAIL = '__ADMIN_EMAIL__'
|
||||||
|
@ -52,8 +52,6 @@ DEFAULT_FROM_EMAIL = '__DEFAULT_FROM_EMAIL__'
|
||||||
# Function that will be called to finalize a user profile:
|
# Function that will be called to finalize a user profile:
|
||||||
YNH_SETUP_USER = 'setup_user.setup_project_user'
|
YNH_SETUP_USER = 'setup_user.setup_project_user'
|
||||||
|
|
||||||
SECRET_KEY = __get_or_create_secret(FINALPATH / 'secret.txt') # /opt/yunohost/$app/secret.txt
|
|
||||||
|
|
||||||
|
|
||||||
if 'axes' not in INSTALLED_APPS:
|
if 'axes' not in INSTALLED_APPS:
|
||||||
INSTALLED_APPS.append('axes') # https://github.com/jazzband/django-axes
|
INSTALLED_APPS.append('axes') # https://github.com/jazzband/django-axes
|
||||||
|
@ -61,6 +59,9 @@ if 'axes' not in INSTALLED_APPS:
|
||||||
INSTALLED_APPS.append('django_yunohost_integration.apps.YunohostIntegrationConfig')
|
INSTALLED_APPS.append('django_yunohost_integration.apps.YunohostIntegrationConfig')
|
||||||
|
|
||||||
|
|
||||||
|
SECRET_KEY = __get_or_create_secret(DATA_DIR_PATH / 'secret.txt') # /home/yunohost.app/$app/secret.txt
|
||||||
|
|
||||||
|
|
||||||
MIDDLEWARE.insert(
|
MIDDLEWARE.insert(
|
||||||
MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
|
MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
|
||||||
# login a user via HTTP_REMOTE_USER header from SSOwat:
|
# login a user via HTTP_REMOTE_USER header from SSOwat:
|
||||||
|
@ -154,8 +155,8 @@ else:
|
||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
|
|
||||||
STATIC_ROOT = str(PUBLIC_PATH / 'static')
|
STATIC_ROOT = str(INSTALL_DIR_PATH / 'static')
|
||||||
MEDIA_ROOT = str(PUBLIC_PATH / 'media')
|
MEDIA_ROOT = str(INSTALL_DIR_PATH / 'media')
|
||||||
|
|
||||||
# _____________________________________________________________________________
|
# _____________________________________________________________________________
|
||||||
# django-ckeditor
|
# django-ckeditor
|
||||||
|
@ -165,16 +166,15 @@ CKEDITOR_BASEPATH = STATIC_URL + 'ckeditor/ckeditor/'
|
||||||
# _____________________________________________________________________________
|
# _____________________________________________________________________________
|
||||||
# Django-dbbackup
|
# Django-dbbackup
|
||||||
|
|
||||||
DBBACKUP_STORAGE_OPTIONS['location'] = str(FINALPATH / 'backups')
|
DBBACKUP_STORAGE_OPTIONS['location'] = str(DATA_DIR_PATH / 'backups')
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# Set log file to e.g.: /var/log/$app/$app.log
|
# Set log file to e.g.: /var/log/$app/$app.log
|
||||||
LOGGING['handlers']['log_file']['filename'] = str(LOG_FILE)
|
LOGGING['handlers']['log_file']['filename'] = str(LOG_FILE_PATH)
|
||||||
|
|
||||||
LOGGING['loggers']['inventory'] = {
|
LOGGING['loggers']['inventory'] = {
|
||||||
'handlers': ['syslog', 'log_file', 'mail_admins'],
|
'handlers': ['syslog', 'log_file', 'mail_admins'],
|
||||||
'level': 'INFO',
|
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
}
|
}
|
||||||
for __logger_name in LOGGING['loggers'].keys():
|
for __logger_name in LOGGING['loggers'].keys():
|
||||||
|
|
|
@ -5,9 +5,9 @@ After=redis.service postgresql.service
|
||||||
[Service]
|
[Service]
|
||||||
User=__APP__
|
User=__APP__
|
||||||
Group=__APP__
|
Group=__APP__
|
||||||
WorkingDirectory=__FINALPATH__/
|
WorkingDirectory=__DATA_DIR__/
|
||||||
|
|
||||||
ExecStart=__FINALPATH__/venv/bin/gunicorn --config __FINALPATH__/gunicorn.conf.py wsgi
|
ExecStart=__DATA_DIR__/venv/bin/gunicorn --config __DATA_DIR__/gunicorn.conf.py wsgi
|
||||||
|
|
||||||
StandardOutput=syslog
|
StandardOutput=syslog
|
||||||
StandardError=syslog
|
StandardError=syslog
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.urls import path
|
||||||
|
|
||||||
|
|
||||||
if settings.PATH_URL:
|
if settings.PATH_URL:
|
||||||
# settings.PATH_URL is the $YNH_APP_ARG_PATH
|
# settings.PATH_URL is __PATH__
|
||||||
# Prefix all urls with "PATH_URL":
|
# Prefix all urls with "PATH_URL":
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# MEDIA_URL contains the "PATH_URL" already:
|
# MEDIA_URL contains the "PATH_URL" already:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# https://yunohost.org/en/packaging_config_panels
|
||||||
# https://github.com/YunoHost/example_ynh/blob/master/config_panel.toml.example
|
# https://github.com/YunoHost/example_ynh/blob/master/config_panel.toml.example
|
||||||
|
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
@ -14,13 +15,16 @@ services = ["__APP__"]
|
||||||
ask = "from email"
|
ask = "from email"
|
||||||
type = "email"
|
type = "email"
|
||||||
help = "Default email address to use for various automated emails."
|
help = "Default email address to use for various automated emails."
|
||||||
bind = "default_from_email:__FINALPATH__/settings.py"
|
#
|
||||||
|
# We can't use "__DATA_DIR__" in bind value, because of this bug:
|
||||||
|
# https://github.com/YunoHost/issues/issues/2283
|
||||||
|
bind = "default_from_email:/home/yunohost.app/__APP__/settings.py"
|
||||||
|
|
||||||
[main.config.admin_email]
|
[main.config.admin_email]
|
||||||
ask = "ADMIN email"
|
ask = "ADMIN email"
|
||||||
type = "email"
|
type = "email"
|
||||||
help = "EMail address for error emails."
|
help = "EMail address for error emails."
|
||||||
bind = "admin_email:__FINALPATH__/settings.py"
|
bind = "admin_email:/home/yunohost.app/__APP__/settings.py"
|
||||||
|
|
||||||
[main.config.debug_enabled]
|
[main.config.debug_enabled]
|
||||||
ask = "DEBUG mode"
|
ask = "DEBUG mode"
|
||||||
|
@ -28,11 +32,11 @@ services = ["__APP__"]
|
||||||
yes = "1"
|
yes = "1"
|
||||||
no = "0"
|
no = "0"
|
||||||
help = "Should be never enabled in production!"
|
help = "Should be never enabled in production!"
|
||||||
bind = "debug_enabled:__FINALPATH__/settings.py"
|
bind = "debug_enabled:/home/yunohost.app/__APP__/settings.py"
|
||||||
|
|
||||||
[main.config.log_level]
|
[main.config.log_level]
|
||||||
type = "string"
|
type = "string"
|
||||||
ask = "Log Level"
|
ask = "Log Level"
|
||||||
choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||||
default = "WARNING"
|
default = "WARNING"
|
||||||
bind = "log_level:__FINALPATH__/settings.py"
|
bind = "log_level:/home/yunohost.app/__APP__/settings.py"
|
||||||
|
|
115
dev-cli.py
Executable file
115
dev-cli.py
Executable file
|
@ -0,0 +1,115 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
bootstrap CLI
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Just call this file, and the magic happens ;)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import venv
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def print_no_pip_error():
|
||||||
|
print('Error: Pip not available!')
|
||||||
|
print('Hint: "apt-get install python3-venv"\n')
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ensurepip import version
|
||||||
|
except ModuleNotFoundError as err:
|
||||||
|
print(err)
|
||||||
|
print('-' * 100)
|
||||||
|
print_no_pip_error()
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
if not version():
|
||||||
|
print_no_pip_error()
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
|
||||||
|
assert sys.version_info >= (3, 9), 'Python version is too old!'
|
||||||
|
|
||||||
|
|
||||||
|
if sys.platform == 'win32': # wtf
|
||||||
|
# Files under Windows, e.g.: .../.venv/Scripts/python.exe
|
||||||
|
BIN_NAME = 'Scripts'
|
||||||
|
FILE_EXT = '.exe'
|
||||||
|
else:
|
||||||
|
# Files under Linux/Mac and all other than Windows, e.g.: .../.venv/bin/python
|
||||||
|
BIN_NAME = 'bin'
|
||||||
|
FILE_EXT = ''
|
||||||
|
|
||||||
|
BASE_PATH = Path(__file__).parent
|
||||||
|
VENV_PATH = BASE_PATH / '.venv'
|
||||||
|
BIN_PATH = VENV_PATH / BIN_NAME
|
||||||
|
PYTHON_PATH = BIN_PATH / f'python{FILE_EXT}'
|
||||||
|
PIP_PATH = BIN_PATH / f'pip{FILE_EXT}'
|
||||||
|
PIP_SYNC_PATH = BIN_PATH / f'pip-sync{FILE_EXT}'
|
||||||
|
|
||||||
|
DEP_LOCK_PATH = BASE_PATH / 'requirements.dev.txt'
|
||||||
|
DEP_HASH_PATH = VENV_PATH / '.dep_hash'
|
||||||
|
|
||||||
|
# script file defined in pyproject.toml as [console_scripts]
|
||||||
|
# (Under Windows: ".exe" not added!)
|
||||||
|
PROJECT_SHELL_SCRIPT = BIN_PATH / 'pyinventory_ynh_dev'
|
||||||
|
|
||||||
|
|
||||||
|
def get_dep_hash():
|
||||||
|
"""Get SHA512 hash from lock file content."""
|
||||||
|
return hashlib.sha512(DEP_LOCK_PATH.read_bytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def store_dep_hash():
|
||||||
|
"""Generate .venv/.dep_hash"""
|
||||||
|
DEP_HASH_PATH.write_text(get_dep_hash())
|
||||||
|
|
||||||
|
|
||||||
|
def venv_up2date():
|
||||||
|
"""Is existing .venv is up-to-date?"""
|
||||||
|
if DEP_HASH_PATH.is_file():
|
||||||
|
return DEP_HASH_PATH.read_text() == get_dep_hash()
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def verbose_check_call(*popen_args):
|
||||||
|
print(f'\n+ {" ".join(str(arg) for arg in popen_args)}\n')
|
||||||
|
return subprocess.check_call(popen_args)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
assert DEP_LOCK_PATH.is_file(), f'File not found: "{DEP_LOCK_PATH}" !'
|
||||||
|
|
||||||
|
# Create virtual env in ".venv/":
|
||||||
|
if not PYTHON_PATH.is_file():
|
||||||
|
print('Create virtual env here:', VENV_PATH.absolute())
|
||||||
|
builder = venv.EnvBuilder(symlinks=True, upgrade=True, with_pip=True)
|
||||||
|
builder.create(env_dir=VENV_PATH)
|
||||||
|
# Update pip
|
||||||
|
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip')
|
||||||
|
|
||||||
|
if not PIP_SYNC_PATH.is_file():
|
||||||
|
# Install pip-tools
|
||||||
|
verbose_check_call(PYTHON_PATH, '-m', 'pip', 'install', '-U', 'pip-tools')
|
||||||
|
|
||||||
|
if not PROJECT_SHELL_SCRIPT.is_file() or not venv_up2date():
|
||||||
|
# install requirements via "pip-sync"
|
||||||
|
verbose_check_call(PIP_SYNC_PATH, str(DEP_LOCK_PATH))
|
||||||
|
|
||||||
|
# install project
|
||||||
|
verbose_check_call(PIP_PATH, 'install', '--no-deps', '-e', '.')
|
||||||
|
store_dep_hash()
|
||||||
|
|
||||||
|
# Call our entry point CLI:
|
||||||
|
try:
|
||||||
|
verbose_check_call(PROJECT_SHELL_SCRIPT, *argv[1:])
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
sys.exit(err.returncode)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv)
|
|
@ -1,12 +1,14 @@
|
||||||
|
[![tests](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/tests.yml)
|
||||||
|
[![codecov](https://codecov.io/github/jedie/pyinventory_ynh/branch/main/graph/badge.svg)](https://app.codecov.io/github/jedie/pyinventory_ynh)
|
||||||
|
[![pyinventory_ynh @ PyPi](https://img.shields.io/pypi/v/pyinventory_ynh?label=pyinventory_ynh%20%40%20PyPi)](https://pypi.org/project/pyinventory_ynh/)
|
||||||
|
[![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/pyproject.toml)
|
||||||
|
[![License GPL-3.0-or-later](https://img.shields.io/pypi/l/pyinventory_ynh)](https://github.com/YunoHost-Apps/pyinventory_ynh/blob/main/LICENSE)
|
||||||
|
|
||||||
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
[PyInventory](https://github.com/jedie/PyInventory) is a libre web-based management to catalog things including state and location etc. using [Python](https://www.python.org/)/[Django](https://www.djangoproject.com/).
|
||||||
|
|
||||||
[![Integration level](https://dash.yunohost.org/integration/pyinventory.svg)](https://dash.yunohost.org/appci/app/pyinventory) [![CI Pipeline](https://ci-apps.yunohost.org/ci/badges/pyinventory.status.svg)](https://ci-apps.yunohost.org/ci/apps/pyinventory/) [![Maintain status](https://ci-apps.yunohost.org/ci/badges/pyinventory.maintain.svg)](https://dash.yunohost.org/appci/app/pyinventory)
|
[![Integration level](https://dash.yunohost.org/integration/pyinventory_ynh.svg)](https://dash.yunohost.org/appci/app/pyinventory_ynh) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/pyinventory_ynh.maintain.svg)
|
||||||
|
[![Install pyinventory_ynh with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=pyinventory_ynh)
|
||||||
|
|
||||||
[![pytest](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/pyinventory_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/pyinventory_ynh)
|
|
||||||
|
|
||||||
![pyinventory @ PyPi](https://img.shields.io/pypi/v/pyinventory?label=pyinventory%20%40%20PyPi)
|
|
||||||
![Python Versions](https://img.shields.io/pypi/pyversions/pyinventory)
|
|
||||||
![License GPL V3+](https://img.shields.io/pypi/l/pyinventory)
|
|
||||||
|
|
||||||
Pull requests welcome ;)
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
|
|
@ -1,152 +1,15 @@
|
||||||
## Settings and upgrades
|
## Settings and upgrades
|
||||||
|
|
||||||
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
Almost everything related to PyInventory's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
You can edit the file `/opt/yunohost/pyinventory/local_settings.py` to enable or disable features.
|
You can edit the file `/home/yunohost.app/django_example/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
Test sending emails:
|
Test sending emails, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ssh admin@yourdomain.tld
|
ssh admin@yourdomain.tld
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
root@yunohost:~# /home/yunohost.app/pyinventory/manage.py sendtestemail --admins
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
How to debug a django YunoHost app, take a look into:
|
||||||
To check current ADMINS run:
|
|
||||||
|
|
||||||
```bash
|
* https://github.com/YunoHost-Apps/django_example_ynh#developer-info
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py sendtestemail --admins
|
|
||||||
```
|
|
||||||
|
|
||||||
If you prefere to send error emails to a extrnal email address, just do something like this:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/pyinventory/local_settings.py
|
|
||||||
```
|
|
||||||
|
|
||||||
To check the effective settings, run this:
|
|
||||||
```bash
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py diffsettings
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
# Miscellaneous
|
|
||||||
|
|
||||||
|
|
||||||
## SSO authentication
|
|
||||||
|
|
||||||
[SSOwat](https://github.com/YunoHost/SSOwat) is fully supported via [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration):
|
|
||||||
|
|
||||||
* First user (`$YNH_APP_ARG_ADMIN`) will be created as Django's super user
|
|
||||||
* All new users will be created as normal users
|
|
||||||
* Login via SSO is fully supported
|
|
||||||
* User Email, First / Last name will be updated from SSO data
|
|
||||||
|
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
* Report a bug about this package: https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
* Report a bug about PyInventory itself: https://github.com/jedie/PyInventory
|
|
||||||
* YunoHost website: https://yunohost.org/
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Developer info
|
|
||||||
|
|
||||||
## package installation / debugging
|
|
||||||
|
|
||||||
Please send your pull request to https://github.com/YunoHost-Apps/pyinventory_ynh
|
|
||||||
|
|
||||||
Try 'main' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/master --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Try 'testing' branch, e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app install https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
or
|
|
||||||
sudo yunohost app upgrade pyinventory -u https://github.com/YunoHost-Apps/pyinventory_ynh/tree/testing --debug
|
|
||||||
```
|
|
||||||
|
|
||||||
To remove call e.g.:
|
|
||||||
```bash
|
|
||||||
sudo yunohost app remove pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Backup / remove / restore cycle, e.g.:
|
|
||||||
```bash
|
|
||||||
yunohost backup create --apps pyinventory
|
|
||||||
yunohost backup list
|
|
||||||
archives:
|
|
||||||
- pyinventory-pre-upgrade1
|
|
||||||
- 20201223-163434
|
|
||||||
yunohost app remove pyinventory
|
|
||||||
yunohost backup restore 20201223-163434 --apps pyinventory
|
|
||||||
```
|
|
||||||
|
|
||||||
Debug installation, e.g.:
|
|
||||||
```bash
|
|
||||||
root@yunohost:~# ls -la /var/www/pyinventory/
|
|
||||||
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/pyinventory/
|
|
||||||
total 58
|
|
||||||
drwxr-xr-x 5 pyinventory pyinventory 11 Dec 8 08:39 .
|
|
||||||
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 460 Dec 8 08:39 gunicorn.conf.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 0 Dec 8 08:39 local_settings.py
|
|
||||||
-rwxr-xr-x 1 pyinventory pyinventory 274 Dec 8 08:39 manage.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 171 Dec 8 08:39 secret.txt
|
|
||||||
drwxr-xr-x 6 pyinventory pyinventory 6 Dec 8 08:37 venv
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 115 Dec 8 08:39 wsgi.py
|
|
||||||
-rw-r--r-- 1 pyinventory pyinventory 4737 Dec 8 08:39 settings.py
|
|
||||||
|
|
||||||
root@yunohost:~# cd /opt/yunohost/pyinventory/
|
|
||||||
root@yunohost:/opt/yunohost/pyinventory# source venv/bin/activate
|
|
||||||
(venv) root@yunohost:/opt/yunohost/pyinventory# ./manage.py check
|
|
||||||
PyInventory v0.8.2 (Django v2.2.17)
|
|
||||||
DJANGO_SETTINGS_MODULE='settings'
|
|
||||||
PROJECT_PATH:/opt/yunohost/pyinventory/venv/lib/python3.7/site-packages
|
|
||||||
BASE_PATH:/opt/yunohost/pyinventory
|
|
||||||
System check identified no issues (0 silenced).
|
|
||||||
|
|
||||||
root@yunohost:~# tail -f /var/log/pyinventory/pyinventory.log
|
|
||||||
root@yunohost:~# cat /etc/systemd/system/pyinventory.service
|
|
||||||
|
|
||||||
root@yunohost:~# systemctl reload-or-restart pyinventory
|
|
||||||
root@yunohost:~# journalctl --unit=pyinventory --follow
|
|
||||||
```
|
|
||||||
|
|
||||||
## local test
|
|
||||||
|
|
||||||
For quicker developing of PyInventory 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/pyinventory_ynh.git
|
|
||||||
~$ cd pyinventory_ynh/
|
|
||||||
~/pyinventory_ynh$ make
|
|
||||||
install-poetry install or update poetry
|
|
||||||
install install PyInventory via poetry
|
|
||||||
update update the sources and installation
|
|
||||||
local-test Run local_test.py to run pyinventory_ynh locally
|
|
||||||
~/pyinventory_ynh$ make install-poetry
|
|
||||||
~/pyinventory_ynh$ make install
|
|
||||||
~/pyinventory_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/`
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
"""
|
|
||||||
Build a "local_test" YunoHost installation and start the Django dev. server against it.
|
|
||||||
|
|
||||||
Run via:
|
|
||||||
make local-test
|
|
||||||
|
|
||||||
see README for details ;)
|
|
||||||
"""
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
from django_yunohost_integration.local_test import create_local_test
|
|
||||||
except ImportError as err:
|
|
||||||
raise ImportError('Did you forget to activate a virtual environment?') from err
|
|
||||||
|
|
||||||
BASE_PATH = Path(__file__).parent
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
create_local_test(
|
|
||||||
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
|
|
||||||
destination=BASE_PATH / 'local_test',
|
|
||||||
runserver=True,
|
|
||||||
extra_replacements={
|
|
||||||
'__DEBUG_ENABLED__': '1',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,47 +0,0 @@
|
||||||
{
|
|
||||||
"name": "PyInventory",
|
|
||||||
"id": "pyinventory",
|
|
||||||
"packaging_format": 1,
|
|
||||||
"description": {
|
|
||||||
"en": "Web based management to catalog things including state and location etc."
|
|
||||||
},
|
|
||||||
"version": "0.19.2~ynh1",
|
|
||||||
"url": "https://github.com/jedie/PyInventory",
|
|
||||||
"upstream": {
|
|
||||||
"license": "GPL-3.0-or-later",
|
|
||||||
"admindoc": "https://github.com/YunoHost-Apps/pyinventory_ynh",
|
|
||||||
"userdoc": "https://github.com/jedie/PyInventory",
|
|
||||||
"code": "https://github.com/jedie/PyInventory"
|
|
||||||
},
|
|
||||||
"license": "GPL-3.0-or-later",
|
|
||||||
"maintainer": {
|
|
||||||
"name": "Jens Diemer",
|
|
||||||
"email": "pyinventory_ynh@jensdiemer.de"
|
|
||||||
},
|
|
||||||
"previous_maintainers": [],
|
|
||||||
"requirements": {
|
|
||||||
"yunohost": ">=11"
|
|
||||||
},
|
|
||||||
"multi_instance": true,
|
|
||||||
"services": [
|
|
||||||
"nginx", "postgresql", "redis"
|
|
||||||
],
|
|
||||||
"arguments": {
|
|
||||||
"install" : [
|
|
||||||
{
|
|
||||||
"name": "domain",
|
|
||||||
"type": "domain"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "path",
|
|
||||||
"type": "path",
|
|
||||||
"example": "/pyinventory",
|
|
||||||
"default": "/pyinventory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "admin",
|
|
||||||
"type": "user"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
110
manifest.toml
Normal file
110
manifest.toml
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
# https://yunohost.org/en/packaging_manifest
|
||||||
|
packaging_format = 2
|
||||||
|
|
||||||
|
id = "pyinventory"
|
||||||
|
name = "PyInventory"
|
||||||
|
description.en = "Web based management to catalog things including state and location etc."
|
||||||
|
|
||||||
|
version = "0.19.3~ynh1"
|
||||||
|
|
||||||
|
maintainers = ["Jens Diemer"]
|
||||||
|
|
||||||
|
|
||||||
|
[upstream]
|
||||||
|
# https://yunohost.org/en/packaging_manifest#upstream-section
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
website = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
|
admindoc = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
|
userdoc = "https://github.com/jedie/PyInventory"
|
||||||
|
code = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
|
|
||||||
|
|
||||||
|
[integration]
|
||||||
|
# https://yunohost.org/en/packaging_manifest#integration-section
|
||||||
|
yunohost = ">=11"
|
||||||
|
architectures = "all"
|
||||||
|
multi_instance = true
|
||||||
|
ldap = true
|
||||||
|
sso = true
|
||||||
|
disk = "50M" # **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ...
|
||||||
|
ram.build = "50M" # **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ...
|
||||||
|
ram.runtime = "50M" # **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ...
|
||||||
|
|
||||||
|
|
||||||
|
[install]
|
||||||
|
[install.domain]
|
||||||
|
# this is a generic question - ask strings are automatically handled by Yunohost's core
|
||||||
|
type = "domain"
|
||||||
|
|
||||||
|
[install.path]
|
||||||
|
# this is a generic question - ask strings are automatically handled by Yunohost's core
|
||||||
|
# setting $path and template variable __PATH__
|
||||||
|
type = "path"
|
||||||
|
default = "/pyinventory_ynh"
|
||||||
|
|
||||||
|
[install.admin]
|
||||||
|
# this is a generic question - ask strings are automatically handled by Yunohost's core
|
||||||
|
type = "user"
|
||||||
|
default = "admin"
|
||||||
|
|
||||||
|
[install.init_main_permission]
|
||||||
|
type = "group"
|
||||||
|
default = "admins"
|
||||||
|
|
||||||
|
[install.default_from_email] # __DEFAULT_FROM_EMAIL__
|
||||||
|
ask.en = "Default email address to use for various automated emails."
|
||||||
|
type = "email"
|
||||||
|
example = "admin@example.com"
|
||||||
|
|
||||||
|
[install.admin_email] # __ADMIN_EMAIL__
|
||||||
|
ask.en = "EMail address for error emails."
|
||||||
|
type = "email"
|
||||||
|
example = "admin@example.com"
|
||||||
|
|
||||||
|
[install.debug_enabled] # __DEBUG_ENABLED__
|
||||||
|
ask.en = "Should be never enabled in production!"
|
||||||
|
type = "select"
|
||||||
|
choices = ["YES", "NO"]
|
||||||
|
default = "NO"
|
||||||
|
|
||||||
|
[install.log_level] # __LOG_LEVEL__
|
||||||
|
ask.en = "Logging level"
|
||||||
|
type = "select"
|
||||||
|
choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||||
|
default = "WARNING"
|
||||||
|
|
||||||
|
|
||||||
|
[resources]
|
||||||
|
[resources.system_user]
|
||||||
|
# This will provision/deprovision a unix system user
|
||||||
|
|
||||||
|
[resources.install_dir]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#install-dir
|
||||||
|
# This will create/remove the install dir as /var/www/$app/
|
||||||
|
# and store the corresponding setting $install_dir and template variable __INSTALL_DIR__
|
||||||
|
|
||||||
|
[resources.data_dir]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#data-dir
|
||||||
|
# This will create/remove the data dir as /home/yunohost.app/$app/
|
||||||
|
# and store the corresponding setting $data_dir and template variable __DATA_DIR__
|
||||||
|
|
||||||
|
[resources.permissions]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#permissions
|
||||||
|
# This will configure SSOwat permission for $domain/$path/
|
||||||
|
# The initial allowed group of user is configured via the init_main_permission question (public=visitors, private=all_users)
|
||||||
|
main.url = "/"
|
||||||
|
|
||||||
|
[resources.ports]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#ports
|
||||||
|
# This will pick a random port for reverse-proxying and store it as the $port setting
|
||||||
|
|
||||||
|
[resources.apt]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#apt
|
||||||
|
# This will automatically install/uninstall the following apt packages
|
||||||
|
packages = "build-essential, python3-dev, python3-pip, python3-venv, git, libpq-dev, postgresql, postgresql-contrib"
|
||||||
|
|
||||||
|
[resources.database]
|
||||||
|
# https://yunohost.org/en/packaging_apps_resources#database
|
||||||
|
# This will automatically provision/deprovison a Postgres DB
|
||||||
|
# and store the corresponding credentials in settings $db_user, $db_name, $db_pwd
|
||||||
|
type = "postgresql"
|
2122
poetry.lock
generated
2122
poetry.lock
generated
File diff suppressed because it is too large
Load diff
7
pyinventory_ynh/__init__.py
Normal file
7
pyinventory_ynh/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
"""
|
||||||
|
pyinventory_ynh
|
||||||
|
Web based management to catalog things including state and location etc.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__version__ = '0.19.3+ynh1'
|
||||||
|
__author__ = 'Jens Diemer <pyinventory_ynh@jensdiemer.de>'
|
0
pyinventory_ynh/cli/__init__.py
Normal file
0
pyinventory_ynh/cli/__init__.py
Normal file
370
pyinventory_ynh/cli/dev.py
Normal file
370
pyinventory_ynh/cli/dev.py
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
"""
|
||||||
|
CLI for development
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import rich_click as click
|
||||||
|
from bx_py_utils.path import assert_is_file
|
||||||
|
from cli_base.cli_tools.subprocess_utils import verbose_check_call
|
||||||
|
from cli_base.cli_tools.version_info import print_version
|
||||||
|
from django_yunohost_integration.local_test import create_local_test
|
||||||
|
from manageprojects.utilities import code_style
|
||||||
|
from manageprojects.utilities.publish import publish_package
|
||||||
|
from rich import print # noqa; noqa
|
||||||
|
from rich_click import RichGroup
|
||||||
|
|
||||||
|
import pyinventory_ynh
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
PACKAGE_ROOT = Path(pyinventory_ynh.__file__).parent.parent
|
||||||
|
assert_is_file(PACKAGE_ROOT / 'pyproject.toml')
|
||||||
|
|
||||||
|
OPTION_ARGS_DEFAULT_TRUE = dict(is_flag=True, show_default=True, default=True)
|
||||||
|
OPTION_ARGS_DEFAULT_FALSE = dict(is_flag=True, show_default=True, default=False)
|
||||||
|
ARGUMENT_EXISTING_DIR = dict(
|
||||||
|
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True, path_type=Path)
|
||||||
|
)
|
||||||
|
ARGUMENT_NOT_EXISTING_DIR = dict(
|
||||||
|
type=click.Path(
|
||||||
|
exists=False,
|
||||||
|
file_okay=False,
|
||||||
|
dir_okay=True,
|
||||||
|
readable=False,
|
||||||
|
writable=True,
|
||||||
|
path_type=Path,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ARGUMENT_EXISTING_FILE = dict(
|
||||||
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, readable=True, path_type=Path)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ClickGroup(RichGroup): # FIXME: How to set the "info_name" easier?
|
||||||
|
def make_context(self, info_name, *args, **kwargs):
|
||||||
|
info_name = './dev-cli.py'
|
||||||
|
return super().make_context(info_name, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(
|
||||||
|
cls=ClickGroup,
|
||||||
|
epilog='Project Homepage: https://github.com/YunoHost-Apps/pyinventory_ynh',
|
||||||
|
)
|
||||||
|
def cli():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
||||||
|
def mypy(verbose: bool = True):
|
||||||
|
"""Run Mypy (configured in pyproject.toml)"""
|
||||||
|
verbose_check_call('mypy', '.', cwd=PACKAGE_ROOT, verbose=verbose, exit_on_error=True)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(mypy)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
||||||
|
def coverage(verbose: bool = True):
|
||||||
|
"""
|
||||||
|
Run and show coverage.
|
||||||
|
"""
|
||||||
|
verbose_check_call('coverage', 'run', verbose=verbose, exit_on_error=True)
|
||||||
|
verbose_check_call('coverage', 'combine', '--append', verbose=verbose, exit_on_error=True)
|
||||||
|
verbose_check_call('coverage', 'report', '--fail-under=30', verbose=verbose, exit_on_error=True)
|
||||||
|
verbose_check_call('coverage', 'xml', verbose=verbose, exit_on_error=True)
|
||||||
|
verbose_check_call('coverage', 'json', verbose=verbose, exit_on_error=True)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(coverage)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def install():
|
||||||
|
"""
|
||||||
|
Run pip-sync and install 'pyinventory_ynh' via pip as editable.
|
||||||
|
"""
|
||||||
|
verbose_check_call('pip-sync', PACKAGE_ROOT / 'requirements.dev.txt')
|
||||||
|
verbose_check_call('pip', 'install', '--no-deps', '-e', '.')
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(install)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def safety():
|
||||||
|
"""
|
||||||
|
Run safety check against current requirements files
|
||||||
|
"""
|
||||||
|
verbose_check_call('safety', 'check', '-r', 'requirements.dev.txt')
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(safety)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def update():
|
||||||
|
"""
|
||||||
|
Update "requirements*.txt" dependencies files
|
||||||
|
"""
|
||||||
|
bin_path = Path(sys.executable).parent
|
||||||
|
|
||||||
|
verbose_check_call(bin_path / 'pip', 'install', '-U', 'pip')
|
||||||
|
verbose_check_call(bin_path / 'pip', 'install', '-U', 'pip-tools')
|
||||||
|
|
||||||
|
extra_env = dict(
|
||||||
|
CUSTOM_COMPILE_COMMAND='./dev-cli.py update',
|
||||||
|
)
|
||||||
|
|
||||||
|
pip_compile_base = [
|
||||||
|
bin_path / 'pip-compile',
|
||||||
|
'--verbose',
|
||||||
|
'--allow-unsafe', # https://pip-tools.readthedocs.io/en/latest/#deprecations
|
||||||
|
'--resolver=backtracking', # https://pip-tools.readthedocs.io/en/latest/#deprecations
|
||||||
|
'--upgrade',
|
||||||
|
'--generate-hashes',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Only "prod" dependencies:
|
||||||
|
verbose_check_call(
|
||||||
|
*pip_compile_base,
|
||||||
|
'pyproject.toml',
|
||||||
|
'--output-file',
|
||||||
|
'conf/requirements.txt',
|
||||||
|
extra_env=extra_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
# dependencies + "dev"-optional-dependencies:
|
||||||
|
verbose_check_call(
|
||||||
|
*pip_compile_base,
|
||||||
|
'pyproject.toml',
|
||||||
|
'--extra=dev',
|
||||||
|
'--output-file',
|
||||||
|
'requirements.dev.txt',
|
||||||
|
extra_env=extra_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
verbose_check_call(bin_path / 'safety', 'check', '-r', 'requirements.dev.txt')
|
||||||
|
|
||||||
|
# Install new dependencies in current .venv:
|
||||||
|
verbose_check_call(bin_path / 'pip-sync', 'requirements.dev.txt')
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(update)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def publish():
|
||||||
|
"""
|
||||||
|
Build and upload this project to PyPi
|
||||||
|
"""
|
||||||
|
_run_unittest_cli(verbose=False, exit_after_run=False) # Don't publish a broken state
|
||||||
|
|
||||||
|
publish_package(
|
||||||
|
module=pyinventory_ynh,
|
||||||
|
package_path=PACKAGE_ROOT,
|
||||||
|
distribution_name='pyinventory_ynh',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(publish)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
||||||
|
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
||||||
|
def fix_code_style(color: bool = True, verbose: bool = False):
|
||||||
|
"""
|
||||||
|
Fix code style of all pyinventory_ynh source code files via darker
|
||||||
|
"""
|
||||||
|
code_style.fix(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(fix_code_style)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option('--color/--no-color', **OPTION_ARGS_DEFAULT_TRUE)
|
||||||
|
@click.option('--verbose/--no-verbose', **OPTION_ARGS_DEFAULT_FALSE)
|
||||||
|
def check_code_style(color: bool = True, verbose: bool = False):
|
||||||
|
"""
|
||||||
|
Check code style by calling darker + flake8
|
||||||
|
"""
|
||||||
|
code_style.check(package_root=PACKAGE_ROOT, color=color, verbose=verbose)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(check_code_style)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def update_test_snapshot_files():
|
||||||
|
"""
|
||||||
|
Update all test snapshot files (by remove and recreate all snapshot files)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def iter_snapshot_files():
|
||||||
|
yield from PACKAGE_ROOT.rglob('*.snapshot.*')
|
||||||
|
|
||||||
|
removed_file_count = 0
|
||||||
|
for item in iter_snapshot_files():
|
||||||
|
item.unlink()
|
||||||
|
removed_file_count += 1
|
||||||
|
print(f'{removed_file_count} test snapshot files removed... run tests...')
|
||||||
|
|
||||||
|
# Just recreate them by running tests:
|
||||||
|
_run_unittest_cli(
|
||||||
|
extra_env=dict(
|
||||||
|
RAISE_SNAPSHOT_ERRORS='0', # Recreate snapshot files without error
|
||||||
|
),
|
||||||
|
verbose=False,
|
||||||
|
exit_after_run=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
new_files = len(list(iter_snapshot_files()))
|
||||||
|
print(f'{new_files} test snapshot files created, ok.\n')
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(update_test_snapshot_files)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_unittest_cli(extra_env=None, verbose=True, exit_after_run=True):
|
||||||
|
"""
|
||||||
|
Call the origin unittest CLI and pass all args to it.
|
||||||
|
"""
|
||||||
|
if extra_env is None:
|
||||||
|
extra_env = dict()
|
||||||
|
|
||||||
|
extra_env.update(
|
||||||
|
dict(
|
||||||
|
PYTHONUNBUFFERED='1',
|
||||||
|
PYTHONWARNINGS='always',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
args = sys.argv[2:]
|
||||||
|
if not args:
|
||||||
|
if verbose:
|
||||||
|
args = ('--verbose', '--locals', '--buffer')
|
||||||
|
else:
|
||||||
|
args = ('--locals', '--buffer')
|
||||||
|
|
||||||
|
verbose_check_call(
|
||||||
|
sys.executable,
|
||||||
|
'-m',
|
||||||
|
'unittest',
|
||||||
|
*args,
|
||||||
|
timeout=15 * 60,
|
||||||
|
extra_env=extra_env,
|
||||||
|
)
|
||||||
|
if exit_after_run:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command() # Dummy command
|
||||||
|
def test():
|
||||||
|
"""
|
||||||
|
Run unittests
|
||||||
|
"""
|
||||||
|
_run_unittest_cli()
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Replace pytest with normal Django unittests:
|
||||||
|
# cli.add_command(test)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_tox():
|
||||||
|
verbose_check_call(sys.executable, '-m', 'tox', *sys.argv[2:])
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command() # Dummy "tox" command
|
||||||
|
def tox():
|
||||||
|
"""
|
||||||
|
Run tox
|
||||||
|
"""
|
||||||
|
_run_tox()
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: cli.add_command(tox)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def version():
|
||||||
|
"""Print version and exit"""
|
||||||
|
# Pseudo command, because the version always printed on every CLI call ;)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(version)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def local_test():
|
||||||
|
"""
|
||||||
|
Build a "local_test" YunoHost installation and start the Django dev. server against it.
|
||||||
|
"""
|
||||||
|
create_local_test(
|
||||||
|
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
|
||||||
|
destination=PACKAGE_ROOT / 'local_test',
|
||||||
|
runserver=True,
|
||||||
|
extra_replacements={
|
||||||
|
'__DEBUG_ENABLED__': '1',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(local_test)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def diffsettings():
|
||||||
|
"""
|
||||||
|
Run "diffsettings" manage command against a "local_test" YunoHost installation.
|
||||||
|
"""
|
||||||
|
destination = PACKAGE_ROOT / 'local_test'
|
||||||
|
create_local_test(
|
||||||
|
django_settings_path=PACKAGE_ROOT / 'conf' / 'settings.py',
|
||||||
|
destination=destination,
|
||||||
|
runserver=False,
|
||||||
|
extra_replacements={
|
||||||
|
'__DEBUG_ENABLED__': '1',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
app_path = destination / 'opt_yunohost'
|
||||||
|
verbose_check_call(sys.executable, app_path / 'manage.py', 'diffsettings', cwd=app_path)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(diffsettings)
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
def pytest():
|
||||||
|
"""
|
||||||
|
Run tests via "pytest"
|
||||||
|
"""
|
||||||
|
verbose_check_call(sys.executable, '-m', 'pytest', *sys.argv[2:], cwd=PACKAGE_ROOT)
|
||||||
|
|
||||||
|
|
||||||
|
cli.add_command(pytest)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print_version(pyinventory_ynh)
|
||||||
|
|
||||||
|
if len(sys.argv) >= 2:
|
||||||
|
# Check if we just pass a command call
|
||||||
|
command = sys.argv[1]
|
||||||
|
if command == 'test':
|
||||||
|
# TODO: Call: _run_unittest_cli()
|
||||||
|
verbose_check_call(sys.executable, '-m', 'pytest', cwd=PACKAGE_ROOT)
|
||||||
|
sys.exit(0)
|
||||||
|
elif command == 'tox':
|
||||||
|
_run_tox()
|
||||||
|
|
||||||
|
# Execute Click CLI:
|
||||||
|
cli()
|
6
pyinventory_ynh/tests/__init__.py
Normal file
6
pyinventory_ynh/tests/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import os
|
||||||
|
import unittest.util
|
||||||
|
|
||||||
|
|
||||||
|
# Hacky way to expand the failed test output:
|
||||||
|
unittest.util._MAX_LENGTH = os.environ.get('UNITTEST_MAX_LENGTH', 300)
|
10
pyinventory_ynh/tests/test_doctests.py
Normal file
10
pyinventory_ynh/tests/test_doctests.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from bx_py_utils.test_utils.unittest_utils import BaseDocTests
|
||||||
|
|
||||||
|
import pyinventory_ynh
|
||||||
|
|
||||||
|
|
||||||
|
class DocTests(BaseDocTests):
|
||||||
|
def test_doctests(self):
|
||||||
|
self.run_doctests(
|
||||||
|
modules=(pyinventory_ynh,),
|
||||||
|
)
|
68
pyinventory_ynh/tests/test_project_setup.py
Normal file
68
pyinventory_ynh/tests/test_project_setup.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import subprocess
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from bx_py_utils.path import assert_is_file
|
||||||
|
from manageprojects.test_utils.click_cli_utils import subprocess_cli
|
||||||
|
from manageprojects.test_utils.project_setup import check_editor_config, get_py_max_line_length
|
||||||
|
from manageprojects.utilities import code_style
|
||||||
|
from packaging.version import Version
|
||||||
|
|
||||||
|
from pyinventory_ynh import __version__
|
||||||
|
from pyinventory_ynh.cli.dev import PACKAGE_ROOT
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectSetupTestCase(TestCase):
|
||||||
|
def test_version(self):
|
||||||
|
self.assertIsNotNone(__version__)
|
||||||
|
|
||||||
|
version = Version(__version__) # Will raise InvalidVersion() if wrong formatted
|
||||||
|
self.assertEqual(str(version), __version__)
|
||||||
|
|
||||||
|
dev_cli_bin = PACKAGE_ROOT / 'dev-cli.py'
|
||||||
|
assert_is_file(dev_cli_bin)
|
||||||
|
|
||||||
|
output = subprocess.check_output([dev_cli_bin, 'version'], text=True)
|
||||||
|
self.assertIn(f'pyinventory_ynh v{__version__}', output)
|
||||||
|
|
||||||
|
def test_code_style(self):
|
||||||
|
dev_cli_bin = PACKAGE_ROOT / 'dev-cli.py'
|
||||||
|
assert_is_file(dev_cli_bin)
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = subprocess_cli(
|
||||||
|
cli_bin=dev_cli_bin,
|
||||||
|
args=('check-code-style',),
|
||||||
|
exit_on_error=False,
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
self.assertIn('.venv/bin/darker', err.stdout) # darker was called?
|
||||||
|
else:
|
||||||
|
if 'Code style: OK' in output:
|
||||||
|
self.assertIn('.venv/bin/darker', output) # darker was called?
|
||||||
|
return # Nothing to fix -> OK
|
||||||
|
|
||||||
|
# Try to "auto" fix code style:
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = subprocess_cli(
|
||||||
|
cli_bin=dev_cli_bin,
|
||||||
|
args=('fix-code-style',),
|
||||||
|
exit_on_error=False,
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError as err:
|
||||||
|
output = err.stdout
|
||||||
|
|
||||||
|
self.assertIn('.venv/bin/darker', output) # darker was called?
|
||||||
|
|
||||||
|
# Check again and display the output:
|
||||||
|
|
||||||
|
try:
|
||||||
|
code_style.check(package_root=PACKAGE_ROOT)
|
||||||
|
except SystemExit as err:
|
||||||
|
self.assertEqual(err.code, 0, 'Code style error, see output above!')
|
||||||
|
|
||||||
|
def test_check_editor_config(self):
|
||||||
|
check_editor_config(package_root=PACKAGE_ROOT)
|
||||||
|
|
||||||
|
max_line_length = get_py_max_line_length(package_root=PACKAGE_ROOT)
|
||||||
|
self.assertEqual(max_line_length, 119)
|
150
pyproject.toml
150
pyproject.toml
|
@ -1,61 +1,87 @@
|
||||||
[tool.poetry]
|
[project]
|
||||||
name = "pyinventory_ynh"
|
name = "pyinventory_ynh"
|
||||||
description = "YunoHost app package for: https://github.com/jedie/PyInventory"
|
dynamic = ["version"]
|
||||||
version = "0.19.2+ynh1"
|
description = "Web based management to catalog things including state and location etc."
|
||||||
authors = ["Jens Diemer <pyinventory_ynh@jensdiemer.de>"]
|
license = {text = "GPL-3.0-or-later"}
|
||||||
homepage = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
readme = "README.md"
|
||||||
license = "GPL-3.0-or-later"
|
authors = [
|
||||||
readme = 'README.md'
|
{name = 'Jens Diemer', email = 'pyinventory_ynh@jensdiemer.de'}
|
||||||
|
]
|
||||||
|
requires-python = ">=3.9" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye)
|
||||||
|
dependencies = [
|
||||||
|
"pyinventory", # https://github.com/jedie/PyInventory
|
||||||
|
#
|
||||||
|
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes
|
||||||
|
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml
|
||||||
|
"django_yunohost_integration[ynh]>=0.6.0", # https://github.com/YunoHost-Apps/django_yunohost_integration
|
||||||
|
#
|
||||||
|
"cli-base-utilities>=0.4.4", # https://github.com/jedie/cli-base-utilities
|
||||||
|
#
|
||||||
|
# indirect depencies, added because we didn't create the requirements.txt with Python <3.11
|
||||||
|
# See: https://github.com/jazzband/pip-tools/issues/1326
|
||||||
|
"async-timeout", # needed by redis for python<=3.11.2
|
||||||
|
]
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"bx_django_utils", # https://github.com/boxine/bx_django_utils
|
||||||
|
"beautifulsoup4", # https://pypi.org/project/beautifulsoup4/
|
||||||
|
#
|
||||||
|
# TODO: Remove "pytest" and use normal unittests ;)
|
||||||
|
"pytest",
|
||||||
|
"pytest-cov",
|
||||||
|
"pytest-django",
|
||||||
|
#
|
||||||
|
"manageprojects>=0.15.0", # https://github.com/jedie/manageprojects
|
||||||
|
"pip-tools", # https://github.com/jazzband/pip-tools/
|
||||||
|
"tox", # https://github.com/tox-dev/tox
|
||||||
|
"coverage", # https://github.com/nedbat/coveragepy
|
||||||
|
"autopep8", # https://github.com/hhatto/autopep8
|
||||||
|
"pyupgrade", # https://github.com/asottile/pyupgrade
|
||||||
|
"flake8", # https://github.com/pycqa/flake8
|
||||||
|
"pyflakes", # https://github.com/PyCQA/pyflakes
|
||||||
|
"codespell", # https://github.com/codespell-project/codespell
|
||||||
|
"EditorConfig", # https://github.com/editorconfig/editorconfig-core-py
|
||||||
|
"safety", # https://github.com/pyupio/safety
|
||||||
|
"mypy", # https://github.com/python/mypy
|
||||||
|
"twine", # https://github.com/pypa/twine
|
||||||
|
|
||||||
[tool.poetry.urls]
|
# https://github.com/akaihola/darker
|
||||||
"Bug Tracker" = "https://github.com/jedie/PyInventory/issues"
|
# https://github.com/ikamensh/flynt
|
||||||
|
# https://github.com/pycqa/isort
|
||||||
|
# https://github.com/pygments/pygments
|
||||||
|
"darker[flynt, isort, color]",
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
# indirect depencies added because of bug:
|
||||||
python = ">=3.9,<4.0.0" # Stay with 3.9 until YunoHost used >=Debian 11 (Bullseye)
|
# https://github.com/pypa/pip/issues/9644 / https://github.com/jazzband/pip-tools/issues/1866
|
||||||
#
|
# to avoid errors like:
|
||||||
pyinventory = ">=0.19.2" # https://github.com/jedie/PyInventory
|
# In --require-hashes mode, all requirements must have their versions pinned with ==. These do not: ...
|
||||||
#
|
"tomli", # Only needed for Python <3.11
|
||||||
# extras "ynh" will install: gunicorn, psycopg2, django-redis and django-axes
|
"exceptiongroup", # needed by pytest
|
||||||
# see: https://github.com/YunoHost-Apps/django_yunohost_integration/blob/main/pyproject.toml
|
]
|
||||||
django_yunohost_integration = {version = ">=0.5.1", extras = ["ynh"]} # https://github.com/YunoHost-Apps/django_yunohost_integration
|
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Documentation = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
|
Source = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[project.scripts]
|
||||||
bx_py_utils = "*" # https://github.com/boxine/bx_py_utils
|
pyinventory_ynh_app = "pyinventory_ynh.__main__:main"
|
||||||
bx_django_utils = "*" # https://github.com/boxine/bx_django_utils
|
pyinventory_ynh_dev = "pyinventory_ynh.cli.dev:main"
|
||||||
tox = ">=4.4.4" # https://github.com/tox-dev/tox
|
|
||||||
coverage= "*" # https://github.com/nedbat/coveragepy
|
|
||||||
flake8 = "*" # https://github.com/pycqa/flake8
|
|
||||||
EditorConfig = "*" # https://github.com/editorconfig/editorconfig-core-py
|
|
||||||
safety = "*" # https://github.com/pyupio/safety
|
|
||||||
mypy = "*" # https://github.com/python/mypy
|
|
||||||
twine = "*" # https://github.com/pypa/twine
|
|
||||||
poetry-publish = "*" # https://github.com/jedie/poetry-publish
|
|
||||||
pytest = "*"
|
|
||||||
pytest-cov = "*"
|
|
||||||
pytest-django = "*"
|
|
||||||
requests = "*" # https://github.com/psf/requests
|
|
||||||
packaging = "*" # https://github.com/pypa/packagi
|
|
||||||
beautifulsoup4 = "*" # https://pypi.org/project/beautifulsoup4/
|
|
||||||
|
|
||||||
# https://github.com/akaihola/darker
|
|
||||||
# https://github.com/ikamensh/flynt
|
|
||||||
# https://github.com/pycqa/isort
|
|
||||||
# https://github.com/pygments/pygments
|
|
||||||
darker = { version = "*", extras = ["flynt", "isort", "color"] }
|
|
||||||
|
|
||||||
tomli = "*" # https://github.com/hukkin/tomli
|
|
||||||
# tomli only needed for Python <3.11, but see bug:
|
|
||||||
# https://github.com/pypa/pip/issues/9644#issuecomment-1456583402
|
|
||||||
#tomli = {version = "*", markers = "python_version < \"3.11\""} # https://github.com/hukkin/tomli
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["setuptools>=61.0", "setuptools_scm>=7.1"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["."]
|
||||||
|
include = ["pyinventory_ynh*"]
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = {attr = "pyinventory_ynh.__version__"}
|
||||||
|
|
||||||
|
|
||||||
[tool.darker]
|
[tool.darker]
|
||||||
src = ['.']
|
src = ['.']
|
||||||
|
# YunoHost apps still use "master" istead of "main", isn't it?
|
||||||
revision = "origin/master..."
|
revision = "origin/master..."
|
||||||
line_length = 119
|
line_length = 119
|
||||||
verbose = true
|
verbose = true
|
||||||
|
@ -77,7 +103,7 @@ log_level = "INFO"
|
||||||
atomic=true
|
atomic=true
|
||||||
profile='black'
|
profile='black'
|
||||||
skip_glob=[".*", "*/htmlcov/*","*/migrations/*","*/local_test/*"]
|
skip_glob=[".*", "*/htmlcov/*","*/migrations/*","*/local_test/*"]
|
||||||
known_first_party=['inventory', 'inventory_project']
|
known_first_party=['inventory', 'inventory_project', 'pyinventory_ynh']
|
||||||
line_length=119
|
line_length=119
|
||||||
lines_after_imports=2
|
lines_after_imports=2
|
||||||
|
|
||||||
|
@ -114,6 +140,10 @@ branch = true
|
||||||
parallel = true
|
parallel = true
|
||||||
concurrency = ["multiprocessing"]
|
concurrency = ["multiprocessing"]
|
||||||
source = ['.']
|
source = ['.']
|
||||||
|
# TODO: pytest -> Django unitests:
|
||||||
|
#command_line = '-m unittest --verbose --locals --buffer'
|
||||||
|
command_line = '-m pytest'
|
||||||
|
disable_warnings = ["couldnt-parse"]
|
||||||
|
|
||||||
[tool.coverage.report]
|
[tool.coverage.report]
|
||||||
omit = ['.*', '*/tests/*']
|
omit = ['.*', '*/tests/*']
|
||||||
|
@ -132,18 +162,32 @@ exclude_lines = [
|
||||||
legacy_tox_ini = """
|
legacy_tox_ini = """
|
||||||
[tox]
|
[tox]
|
||||||
isolated_build = True
|
isolated_build = True
|
||||||
envlist = py{311,310,39}
|
envlist = py{312,311,310,39}
|
||||||
skip_missing_interpreters = True
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
passenv = *
|
passenv = *
|
||||||
skip_install = true
|
skip_install = true
|
||||||
allowlist_externals = make
|
commands_pre =
|
||||||
|
pip install -U pip-tools
|
||||||
|
pip-sync requirements.dev.txt
|
||||||
commands =
|
commands =
|
||||||
make pytest
|
{envpython} -m coverage run --context='{envname}'
|
||||||
|
{envpython} -m coverage combine --append
|
||||||
|
{envpython} -m coverage xml
|
||||||
|
{envpython} -m coverage report
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
warn_unused_configs = true
|
||||||
|
ignore_missing_imports = true
|
||||||
|
allow_redefinition = true # https://github.com/python/mypy/issues/7165
|
||||||
|
show_error_codes = true
|
||||||
|
plugins = []
|
||||||
|
exclude = ['.venv', 'tests']
|
||||||
|
|
||||||
|
|
||||||
[manageprojects] # https://github.com/jedie/manageprojects
|
[manageprojects] # https://github.com/jedie/manageprojects
|
||||||
initial_revision = "b204761"
|
initial_revision = "b204761"
|
||||||
initial_date = 2022-12-21T20:25:20+01:00
|
initial_date = 2022-12-21T20:25:20+01:00
|
||||||
|
@ -160,11 +204,13 @@ upstream_url = "https://github.com/jedie/PyInventory"
|
||||||
ynh_app_pkg_name = "pyinventory_ynh"
|
ynh_app_pkg_name = "pyinventory_ynh"
|
||||||
ynh_app_url = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
ynh_app_url = "https://github.com/YunoHost-Apps/pyinventory_ynh"
|
||||||
bug_tracker_url = "https://github.com/jedie/PyInventory/issues"
|
bug_tracker_url = "https://github.com/jedie/PyInventory/issues"
|
||||||
upstream_version = "0.17.0"
|
upstream_version = "0.19.2"
|
||||||
ynh_version = "1"
|
ynh_version = "1"
|
||||||
package_description = "Web based management to catalog things including state and location etc."
|
package_description = "Web based management to catalog things including state and location etc."
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
_template = "https://github.com/jedie/cookiecutter_templates/"
|
_template = "https://github.com/jedie/cookiecutter_templates/"
|
||||||
applied_migrations = [
|
applied_migrations = [
|
||||||
"877e2ec", # 2023-08-17T20:54:24+02:00
|
"877e2ec", # 2023-08-17T20:54:24+02:00
|
||||||
|
"be3f649", # 2023-08-22T19:36:57+02:00
|
||||||
|
"c1a9d97", # 2023-11-01T19:59:17+01:00
|
||||||
]
|
]
|
||||||
|
|
1139
requirements.dev.txt
Normal file
1139
requirements.dev.txt
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,15 +4,6 @@
|
||||||
# RETRIEVE ARGUMENTS FROM THE MANIFEST
|
# RETRIEVE ARGUMENTS FROM THE MANIFEST
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
domain=$YNH_APP_ARG_DOMAIN
|
|
||||||
path_url=$YNH_APP_ARG_PATH
|
|
||||||
|
|
||||||
admin=$YNH_APP_ARG_ADMIN
|
|
||||||
|
|
||||||
# Currently not used: PyInventory has no public pages, yet!
|
|
||||||
is_public=$YNH_APP_ARG_IS_PUBLIC
|
|
||||||
app=$YNH_APP_INSTANCE_NAME
|
|
||||||
|
|
||||||
# Transfer the main SSO domain to the App:
|
# Transfer the main SSO domain to the App:
|
||||||
ynh_current_host=$(cat /etc/yunohost/current_host)
|
ynh_current_host=$(cat /etc/yunohost/current_host)
|
||||||
__YNH_CURRENT_HOST__=${ynh_current_host}
|
__YNH_CURRENT_HOST__=${ynh_current_host}
|
||||||
|
@ -22,7 +13,7 @@ __YNH_CURRENT_HOST__=${ynh_current_host}
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
# 'debug_enabled' -> '__DEBUG_ENABLED__' -> settings.DEBUG
|
# 'debug_enabled' -> '__DEBUG_ENABLED__' -> settings.DEBUG
|
||||||
debug_enabled="0"
|
debug_enabled="NO" # "YES" or "NO" string
|
||||||
|
|
||||||
# 'log_level' -> '__LOG_LEVEL__' -> settings.LOG_LEVEL
|
# 'log_level' -> '__LOG_LEVEL__' -> settings.LOG_LEVEL
|
||||||
log_level="WARNING"
|
log_level="WARNING"
|
||||||
|
@ -37,23 +28,62 @@ default_from_email="${app}@${domain}"
|
||||||
# SET CONSTANTS
|
# SET CONSTANTS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
public_path=/var/www/$app
|
# e.g.: point pip cache to: /home/yunohost.app/$app/.cache/
|
||||||
final_path=/opt/yunohost/$app
|
XDG_CACHE_HOME="$data_dir/.cache/"
|
||||||
|
|
||||||
log_path=/var/log/$app
|
log_path=/var/log/$app
|
||||||
log_file="${log_path}/${app}.log"
|
log_file="${log_path}/${app}.log"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# COMMON VARIABLES
|
# HELPERS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
# Needed base dependencies:
|
myynh_setup_python_venv() {
|
||||||
pkg_dependencies="build-essential python3-dev python3-pip python3-venv git"
|
# Always recreate everything fresh with current python version
|
||||||
|
ynh_secure_remove "$data_dir/venv"
|
||||||
|
|
||||||
# Postgres and Python's "psycopg2":
|
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||||
pkg_dependencies="${pkg_dependencies} libpq-dev postgresql postgresql-contrib"
|
python3 -m venv --without-pip "$data_dir/venv"
|
||||||
|
|
||||||
# dependencies used by the app
|
chown -c -R "$app:" "$data_dir"
|
||||||
pkg_dependencies="${pkg_dependencies} libjpeg-dev"
|
|
||||||
|
# run source in a 'sub shell'
|
||||||
|
(
|
||||||
|
set +o nounset
|
||||||
|
source "$data_dir/venv/bin/activate"
|
||||||
|
set -o nounset
|
||||||
|
set -x
|
||||||
|
ynh_exec_as $app $data_dir/venv/bin/python3 -m ensurepip
|
||||||
|
ynh_exec_as $app $data_dir/venv/bin/pip3 install --upgrade wheel pip setuptools
|
||||||
|
ynh_exec_as $app $data_dir/venv/bin/pip3 install --no-deps -r "$data_dir/requirements.txt"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
myynh_setup_log_file() {
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "$log_file")"
|
||||||
|
touch "$log_file"
|
||||||
|
|
||||||
|
chown -c -R $app:$app "$log_path"
|
||||||
|
chmod -c o-rwx "$log_path"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
myynh_fix_file_permissions() {
|
||||||
|
(
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# /var/www/$app/
|
||||||
|
chown -c -R "$app:www-data" "$install_dir"
|
||||||
|
chmod -c o-rwx "$install_dir"
|
||||||
|
|
||||||
|
# /home/yunohost.app/$app/
|
||||||
|
chown -c -R "$app:" "$data_dir"
|
||||||
|
chmod -c o-rwx "$data_dir"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# Redis HELPERS
|
# Redis HELPERS
|
||||||
|
|
|
@ -9,21 +9,6 @@
|
||||||
source ../settings/scripts/_common.sh
|
source ../settings/scripts/_common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
ynh_abort_if_errors
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# LOAD SETTINGS
|
|
||||||
#=================================================
|
|
||||||
ynh_print_info --message="Loading installation settings..."
|
|
||||||
|
|
||||||
app=$YNH_APP_INSTANCE_NAME
|
|
||||||
|
|
||||||
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
|
|
||||||
final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
|
|
||||||
db_name=$(ynh_app_setting_get --app="$app" --key=db_name)
|
|
||||||
|
|
||||||
domain=$(ynh_app_setting_get --app="$app" --key=domain)
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# DECLARE DATA AND CONF FILES TO BACKUP
|
# DECLARE DATA AND CONF FILES TO BACKUP
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -33,8 +18,11 @@ ynh_print_info --message="Declaring files to be backed up..."
|
||||||
# BACKUP THE APP MAIN DIR
|
# BACKUP THE APP MAIN DIR
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
ynh_backup --src_path="$final_path"
|
# /var/www/$app/
|
||||||
ynh_backup --src_path="$public_path"
|
ynh_backup --src_path="$install_dir"
|
||||||
|
|
||||||
|
# /home/yunohost.app/$app/
|
||||||
|
ynh_backup --src_path="$data_dir"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# BACKUP THE NGINX CONFIGURATION
|
# BACKUP THE NGINX CONFIGURATION
|
||||||
|
|
|
@ -6,81 +6,9 @@
|
||||||
# IMPORT GENERIC HELPERS
|
# IMPORT GENERIC HELPERS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
YNH_APP_ARG_DOMAIN=$YNH_APP_NEW_DOMAIN
|
|
||||||
YNH_APP_ARG_PATH=$YNH_APP_NEW_PATH
|
|
||||||
|
|
||||||
source _common.sh
|
source _common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# RETRIEVE ARGUMENTS
|
|
||||||
#=================================================
|
|
||||||
|
|
||||||
old_domain=$YNH_APP_OLD_DOMAIN
|
|
||||||
old_path=$YNH_APP_OLD_PATH
|
|
||||||
|
|
||||||
new_domain=$YNH_APP_NEW_DOMAIN
|
|
||||||
new_path=$YNH_APP_NEW_PATH
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# LOAD SETTINGS
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Loading installation settings..."
|
|
||||||
|
|
||||||
admin=$(ynh_app_setting_get --app="$app" --key=admin)
|
|
||||||
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)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
# config_panel.toml settings:
|
|
||||||
|
|
||||||
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
|
|
||||||
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
|
|
||||||
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
|
|
||||||
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=40
|
|
||||||
|
|
||||||
# Backup the current version of the app
|
|
||||||
ynh_backup_before_upgrade
|
|
||||||
ynh_clean_setup () {
|
|
||||||
# Remove the new domain config file, the remove script won't do it as it doesn't know yet its location.
|
|
||||||
ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf"
|
|
||||||
|
|
||||||
# restore it if the upgrade fails
|
|
||||||
ynh_restore_upgradebackup
|
|
||||||
}
|
|
||||||
# Exit if an error occurs during the execution of the script
|
|
||||||
ynh_abort_if_errors
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# CHECK WHICH PARTS SHOULD BE CHANGED
|
|
||||||
#=================================================
|
|
||||||
|
|
||||||
change_domain=0
|
|
||||||
if [ "$old_domain" != "$new_domain" ]
|
|
||||||
then
|
|
||||||
change_domain=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
change_path=0
|
|
||||||
if [ "$old_path" != "$new_path" ]
|
|
||||||
then
|
|
||||||
change_path=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# STANDARD MODIFICATIONS
|
# STANDARD MODIFICATIONS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -88,66 +16,31 @@ fi
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Stopping systemd service '$app'..."
|
ynh_script_progression --message="Stopping systemd service '$app'..."
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="stop"
|
ynh_systemd_action --service_name=$app --action="stop" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# STANDARD MODIFICATIONS
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# MODIFY URL IN NGINX CONF
|
# MODIFY URL IN NGINX CONF
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Updating nginx web server configuration..."
|
ynh_script_progression --message="Updating nginx web server configuration..."
|
||||||
|
|
||||||
nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf
|
ynh_change_url_nginx_config
|
||||||
|
|
||||||
# Change the path in the nginx config file
|
|
||||||
if [ $change_path -eq 1 ]
|
|
||||||
then
|
|
||||||
# Make a backup of the original nginx config file if modified
|
|
||||||
ynh_backup_if_checksum_is_different --file="$nginx_conf_path"
|
|
||||||
# Set global variables for nginx helper
|
|
||||||
domain="$old_domain"
|
|
||||||
path_url="$new_path"
|
|
||||||
# Create a dedicated nginx config
|
|
||||||
ynh_add_nginx_config "public_path" "port"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Change the domain for nginx
|
|
||||||
if [ $change_domain -eq 1 ]
|
|
||||||
then
|
|
||||||
# Delete file checksum for the old conf file location
|
|
||||||
ynh_delete_file_checksum --file="$nginx_conf_path"
|
|
||||||
mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf
|
|
||||||
# Store file checksum for the new config file location
|
|
||||||
ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# SPECIFIC MODIFICATIONS
|
# UPDATE DJANGO SETTINGS
|
||||||
#=================================================
|
#=================================================
|
||||||
# MODIFY SETTINGS
|
ynh_script_progression --message="Update $app settings file..." --weight=1
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Modify $app config file..."
|
|
||||||
|
|
||||||
domain=$YNH_APP_NEW_DOMAIN
|
path=$new_path
|
||||||
path_url=$YNH_APP_NEW_PATH
|
domain=$new_domain
|
||||||
|
|
||||||
ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
|
ynh_add_config --template="settings.py" --destination="$data_dir/settings.py"
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# GENERIC FINALISATION
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# START SYSTEMD SERVICE
|
# START SYSTEMD SERVICE
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="start"
|
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# RELOAD NGINX
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Reloading nginx web server..."
|
|
||||||
|
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# END OF SCRIPT
|
# END OF SCRIPT
|
||||||
|
|
228
scripts/install
228
scripts/install
|
@ -7,159 +7,93 @@
|
||||||
source _common.sh
|
source _common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
#=================================================
|
# Install parameters are automatically saved as settings
|
||||||
# MANAGE SCRIPT FAILURE
|
#
|
||||||
#=================================================
|
# Settings are automatically loaded as bash variables
|
||||||
|
# in every app script context, therefore typically these will exist:
|
||||||
|
# - $domain
|
||||||
|
# - $path
|
||||||
|
# - $language
|
||||||
|
# ... etc
|
||||||
|
#
|
||||||
|
# Resources defined in the manifest are provisioned prior to this script
|
||||||
|
# and corresponding settings are also available, such as:
|
||||||
|
# - $install_dir
|
||||||
|
# - $port
|
||||||
|
# - $db_name
|
||||||
|
# ...
|
||||||
|
|
||||||
# Exit if an error occurs during the execution of the script
|
#
|
||||||
ynh_abort_if_errors
|
# $app is the app id (i.e. 'example' for first install,
|
||||||
|
# or 'example__2', '__3', ... for multi-instance installs)
|
||||||
|
#
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SETTINGS
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Storing installation settings..."
|
||||||
|
|
||||||
|
# Logging:
|
||||||
|
log_file="/var/log/$app/$app.log"
|
||||||
|
ynh_app_setting_set --app=$app --key=log_file --value="$log_file"
|
||||||
|
|
||||||
|
# Redis:
|
||||||
|
redis_db=$(ynh_redis_get_free_db)
|
||||||
|
ynh_app_setting_set --app=$app --key=redis_db --value="$redis_db"
|
||||||
|
|
||||||
|
# App settings:
|
||||||
|
ynh_app_setting_set --app=$app --key=default_from_email --value="$default_from_email"
|
||||||
|
ynh_app_setting_set --app=$app --key=admin_email --value="$admin_email"
|
||||||
|
ynh_app_setting_set --app=$app --key=debug_enabled --value="$debug_enabled"
|
||||||
|
ynh_app_setting_set --app=$app --key=log_level --value="$log_level"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
|
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Validating installation parameters..."
|
ynh_script_progression --message="Validating installation parameters..."
|
||||||
|
|
||||||
# Path for e.g. "static" files, served by nginx:
|
mkdir -p "$install_dir/media" "$install_dir/static"
|
||||||
test ! -e "$public_path" || ynh_die --message="This path already contains a folder"
|
|
||||||
|
|
||||||
# Path for own config files, e.g.: Django's settings.py:
|
|
||||||
test ! -e "$final_path" || ynh_die --message="This path already contains a folder"
|
|
||||||
|
|
||||||
# Register (book) web path
|
|
||||||
ynh_webpath_register --app="$app" --domain="$domain" --path_url="$path_url"
|
|
||||||
|
|
||||||
mkdir -p "$public_path/media" "$public_path/static"
|
|
||||||
mkdir -p "$final_path"
|
|
||||||
|
|
||||||
mkdir -p "$log_path"
|
|
||||||
touch "${log_file}"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# STORE SETTINGS FROM MANIFEST
|
# SETUP LOG FILE
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Storing installation settings..."
|
ynh_script_progression --message="Setup logging..."
|
||||||
|
|
||||||
ynh_app_setting_set --app="$app" --key=admin --value="$admin"
|
myynh_setup_log_file
|
||||||
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"
|
|
||||||
|
|
||||||
ynh_app_setting_set --app="$app" --key=domain --value="$domain"
|
# Use logrotate to manage application logfile(s)
|
||||||
ynh_app_setting_set --app="$app" --key=path --value="$path_url"
|
ynh_use_logrotate --logfile="$log_file" --specific_user=$app
|
||||||
|
|
||||||
# Find a free port
|
|
||||||
port=$(ynh_find_port --port=8000)
|
|
||||||
# Set port as application 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)
|
|
||||||
|
|
||||||
redis_db=$(ynh_redis_get_free_db)
|
|
||||||
ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db"
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
|
||||||
# config_panel.toml settings:
|
|
||||||
|
|
||||||
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
|
|
||||||
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
|
|
||||||
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
|
|
||||||
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# STANDARD MODIFICATIONS
|
|
||||||
#=================================================
|
|
||||||
# INSTALL DEPENDENCIES
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Installing $app dependencies..." --weight=20
|
|
||||||
|
|
||||||
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# CREATE A PostgreSQL DATABASE
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Creating a PostgreSQL database..."
|
|
||||||
|
|
||||||
db_name=$(ynh_sanitize_dbid --db_name="$app")
|
|
||||||
db_user=$db_name
|
|
||||||
ynh_app_setting_set --app="$app" --key=db_name --value="$db_name"
|
|
||||||
|
|
||||||
ynh_psql_test_if_first_run
|
|
||||||
|
|
||||||
# Initialize database and store postgres password for upgrade
|
|
||||||
ynh_psql_setup_db --db_user="$db_user" --db_name="$db_name"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# NGINX CONFIGURATION
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Configuring nginx web server..."
|
|
||||||
|
|
||||||
# Create a dedicated nginx config
|
|
||||||
# https://yunohost.org/en/contribute/packaging_apps/helpers
|
|
||||||
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
|
|
||||||
ynh_add_nginx_config "public_path" "port"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# CREATE DEDICATED USER
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Configuring system user '$app'..."
|
|
||||||
|
|
||||||
# A home directory for venv and settings etc.
|
|
||||||
ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# PYTHON VIRTUALENV
|
# PYTHON VIRTUALENV
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Create Python virtualenv..." --weight=5
|
ynh_script_progression --message="Create and setup Python virtualenv..." --weight=45
|
||||||
|
cp ../conf/requirements.txt "$data_dir/requirements.txt"
|
||||||
# Always recreate everything fresh with current python version
|
myynh_setup_python_venv
|
||||||
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"
|
|
||||||
|
|
||||||
cp ../conf/requirements.txt "$final_path/requirements.txt"
|
|
||||||
chown -R "$app:" "$final_path"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# PIP INSTALLATION
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Install project via pip..." --weight=45
|
|
||||||
|
|
||||||
#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"
|
|
||||||
)
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# copy config files
|
# copy config files
|
||||||
# ================================================
|
# ================================================
|
||||||
ynh_script_progression --message="Create $app configuration files..."
|
ynh_script_progression --message="Create $app configuration files..."
|
||||||
|
|
||||||
ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py"
|
ynh_add_config --template="gunicorn.conf.py" --destination="$data_dir/gunicorn.conf.py"
|
||||||
|
|
||||||
ynh_add_config --template="manage.py" --destination="$final_path/manage.py"
|
ynh_add_config --template="manage.py" --destination="$data_dir/manage.py"
|
||||||
chmod +x "$final_path/manage.py"
|
chmod -c +x "$data_dir/manage.py"
|
||||||
|
|
||||||
ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
|
ynh_add_config --template="settings.py" --destination="$data_dir/settings.py"
|
||||||
ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
|
ynh_add_config --template="setup_user.py" --destination="$data_dir/setup_user.py"
|
||||||
ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
|
ynh_add_config --template="urls.py" --destination="$data_dir/urls.py"
|
||||||
ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py"
|
ynh_add_config --template="wsgi.py" --destination="$data_dir/wsgi.py"
|
||||||
|
|
||||||
touch "$final_path/local_settings.py"
|
touch "$data_dir/local_settings.py"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# MIGRATE / COLLECTSTATIC / CREATEADMIN
|
# MIGRATE / COLLECTSTATIC / CREATEADMIN
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
||||||
|
|
||||||
cd "$final_path" || exit
|
cd "$data_dir" || exit
|
||||||
|
|
||||||
# Just for debugging:
|
# Just for debugging:
|
||||||
./manage.py diffsettings
|
./manage.py diffsettings
|
||||||
|
@ -174,72 +108,46 @@ cd "$final_path" || exit
|
||||||
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
|
# 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
|
./manage.py check --deploy || true
|
||||||
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# SETUP LOGROTATE
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Configuring log rotation..."
|
|
||||||
|
|
||||||
# Use logrotate to manage app-specific logfile(s)
|
|
||||||
ynh_use_logrotate "$log_file"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# INTEGRATE SERVICE IN YUNOHOST
|
# INTEGRATE SERVICE IN YUNOHOST
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Integrating service in YunoHost..."
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
yunohost service add $app --log="${log_file}"
|
yunohost service add $app
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# GENERIC FINALIZATION
|
# GENERIC FINALIZATION
|
||||||
#=================================================
|
#=================================================
|
||||||
# SECURE FILES AND DIRECTORIES
|
# SECURE FILES AND DIRECTORIES
|
||||||
#=================================================
|
#=================================================
|
||||||
|
ynh_script_progression --message="Set file permissions..."
|
||||||
# Set permissions to app files
|
myynh_fix_file_permissions
|
||||||
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"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# SETUP SYSTEMD
|
# SETUP SYSTEMD
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
# https://yunohost.org/en/contribute/packaging_apps/helpers
|
# https://yunohost.org/en/packaging_apps_helpers#ynh-add-systemd-config
|
||||||
# https://github.com/YunoHost/yunohost/blob/dev/helpers/systemd
|
# https://github.com/YunoHost/yunohost/blob/dev/helpers/systemd
|
||||||
ynh_add_systemd_config --service="$app" --template="systemd.service"
|
ynh_add_systemd_config --service=$app --template="systemd.service"
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# SETUP SSOWAT
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Configuring SSOwat..."
|
|
||||||
|
|
||||||
# Make app public if necessary or protect it
|
|
||||||
if [ $is_public -eq 1 ]
|
|
||||||
then
|
|
||||||
# Everyone can access the app.
|
|
||||||
# The "main" permission is automatically created before the install script.
|
|
||||||
ynh_permission_update --permission "main" --add "visitors"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# Start the app server via systemd
|
# Start the app server via systemd
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="start"
|
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# RELOAD NGINX
|
# NGINX CONFIGURATION
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Reloading nginx web server..."
|
ynh_script_progression --message="Configuring nginx web server..."
|
||||||
|
|
||||||
ynh_systemd_action --service_name="nginx" --action="reload"
|
# Create a dedicated nginx config
|
||||||
|
# https://yunohost.org/en/contribute/packaging_apps/helpers
|
||||||
|
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
|
||||||
|
ynh_add_nginx_config "public_path" "port"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# END OF SCRIPT
|
# END OF SCRIPT
|
||||||
|
|
|
@ -9,17 +9,6 @@
|
||||||
source _common.sh
|
source _common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# LOAD SETTINGS
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Loading installation settings..."
|
|
||||||
|
|
||||||
domain=$(ynh_app_setting_get --app="$app" --key=domain)
|
|
||||||
db_name=$(ynh_app_setting_get --app="$app" --key=db_name)
|
|
||||||
db_user=$db_name
|
|
||||||
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
|
|
||||||
final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# STANDARD REMOVE
|
# STANDARD REMOVE
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -27,10 +16,10 @@ final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
||||||
# Remove a service from the admin panel, added by `yunohost service add`
|
# Remove a service from the admin panel, added by `yunohost service add`
|
||||||
if yunohost service status "$app" >/dev/null 2>&1
|
if yunohost service status $app >/dev/null 2>&1
|
||||||
then
|
then
|
||||||
ynh_script_progression --message="Removing $app service integration..."
|
ynh_script_progression --message="Removing $app service integration..."
|
||||||
yunohost service remove "$app"
|
yunohost service remove $app
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -38,15 +27,7 @@ fi
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Stopping and removing systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Stopping and removing systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_remove_systemd_config --service="$app"
|
ynh_remove_systemd_config --service=$app
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# REMOVE THE PostgreSQL DATABASE
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Removing the PostgreSQL database..."
|
|
||||||
|
|
||||||
# Remove a database if it exists, along with the associated user
|
|
||||||
ynh_psql_remove_db --db_user=$db_user --db_name=$db_name
|
|
||||||
|
|
||||||
##=================================================
|
##=================================================
|
||||||
## REMOVE REDIS DB
|
## REMOVE REDIS DB
|
||||||
|
@ -54,22 +35,16 @@ ynh_psql_remove_db --db_user=$db_user --db_name=$db_name
|
||||||
|
|
||||||
ynh_redis_remove_db
|
ynh_redis_remove_db
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# REMOVE DEPENDENCIES
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Removing dependencies..." --weight=10
|
|
||||||
|
|
||||||
# Remove metapackage and its dependencies
|
|
||||||
ynh_exec_warn_less ynh_remove_app_dependencies
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# REMOVE APP MAIN DIR
|
# REMOVE APP MAIN DIR
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Removing app main directory..."
|
ynh_script_progression --message="Removing app main directory..."
|
||||||
|
|
||||||
# Remove the app directory securely
|
# /var/www/$app/
|
||||||
ynh_secure_remove --file="$public_path"
|
ynh_secure_remove --file="$install_dir"
|
||||||
ynh_secure_remove --file="$final_path"
|
|
||||||
|
# /home/yunohost.app/$app/
|
||||||
|
ynh_secure_remove --file="$data_dir"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# REMOVE NGINX CONFIGURATION
|
# REMOVE NGINX CONFIGURATION
|
||||||
|
@ -87,16 +62,6 @@ ynh_script_progression --message="Removing logrotate configuration..."
|
||||||
# Remove the app-specific logrotate config
|
# Remove the app-specific logrotate config
|
||||||
ynh_remove_logrotate
|
ynh_remove_logrotate
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# GENERIC FINALIZATION
|
|
||||||
#=================================================
|
|
||||||
# REMOVE DEDICATED USER
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Removing the dedicated system user..."
|
|
||||||
|
|
||||||
# Delete a system user
|
|
||||||
ynh_system_user_delete --username="$app"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# END OF SCRIPT
|
# END OF SCRIPT
|
||||||
#=================================================
|
#=================================================
|
||||||
|
|
106
scripts/restore
106
scripts/restore
|
@ -9,39 +9,12 @@
|
||||||
source ../settings/scripts/_common.sh
|
source ../settings/scripts/_common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# MANAGE SCRIPT FAILURE
|
|
||||||
#=================================================
|
|
||||||
|
|
||||||
ynh_abort_if_errors
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# LOAD SETTINGS
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Loading settings..."
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
domain=$(ynh_app_setting_get --app="$app" --key=domain)
|
|
||||||
path_url=$(ynh_app_setting_get --app="$app" --key=path)
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# CHECK IF THE APP CAN BE RESTORED
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Validating restoration parameters..."
|
|
||||||
|
|
||||||
test ! -d $final_path \
|
|
||||||
|| ynh_die --message="There is already a directory: $final_path "
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# STANDARD RESTORATION STEPS
|
# STANDARD RESTORATION STEPS
|
||||||
#=================================================
|
#=================================================
|
||||||
# RESTORE THE NGINX CONFIGURATION
|
# RESTORE THE NGINX CONFIGURATION
|
||||||
#=================================================
|
#=================================================
|
||||||
|
ynh_script_progression --message="Restoring the NGINX web server configuration..." --weight=1
|
||||||
|
|
||||||
ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
|
ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
|
||||||
|
@ -50,74 +23,31 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Restoring $app main directory..."
|
ynh_script_progression --message="Restoring $app main directory..."
|
||||||
|
|
||||||
ynh_restore_file --origin_path="$final_path"
|
ynh_restore_file --origin_path="$install_dir"
|
||||||
ynh_restore_file --origin_path="$public_path"
|
ynh_restore_file --origin_path="$data_dir"
|
||||||
|
|
||||||
#=================================================
|
ynh_script_progression --message="Set file permissions..."
|
||||||
# RECREATE THE DEDICATED USER
|
myynh_fix_file_permissions
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Recreating the dedicated system user..."
|
|
||||||
|
|
||||||
# Create the dedicated user (if not existing)
|
|
||||||
ynh_system_user_create --username=$app --home_dir="$final_path" --use_shell
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# RESTORE USER RIGHTS
|
|
||||||
#=================================================
|
|
||||||
|
|
||||||
# Restore permissions on app files
|
|
||||||
chown -R "$app:www-data" "$public_path"
|
|
||||||
chown -R "$app:" "$final_path"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# SPECIFIC RESTORATION
|
|
||||||
#=================================================
|
|
||||||
# REINSTALL DEPENDENCIES
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Reinstalling dependencies..." --weight=20
|
|
||||||
|
|
||||||
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# PYTHON VIRTUALENV
|
# PYTHON VIRTUALENV
|
||||||
# Maybe the backup contains a other Python version
|
# Maybe the backup contains a other Python version
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
|
ynh_script_progression --message="Create and setup Python virtualenv..." --weight=45
|
||||||
|
|
||||||
# Always recreate everything fresh with current python version
|
myynh_setup_python_venv
|
||||||
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"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# PIP INSTALLATION
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Install project via pip..." --weight=45
|
|
||||||
#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
|
# RESTORE THE PostgreSQL DATABASE
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=5
|
ynh_script_progression --message="Restoring the PostgreSQL database..." --weight=5
|
||||||
|
|
||||||
ynh_psql_test_if_first_run
|
|
||||||
ynh_psql_setup_db --db_user="$db_user" --db_name="$db_name" --db_pwd="$db_pwd"
|
|
||||||
ynh_psql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql
|
ynh_psql_connect_as --user=$db_user --password=$db_pwd --database=$db_name < ./db.sql
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# RESTORE SYSTEMD
|
# RESTORE SYSTEMD
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Restoring the systemd configuration..."
|
ynh_script_progression --message="Restoring the systemd $app configuration..."
|
||||||
|
|
||||||
ynh_restore_file --origin_path="/etc/systemd/system/$app.service"
|
ynh_restore_file --origin_path="/etc/systemd/system/$app.service"
|
||||||
systemctl enable $app.service --quiet
|
systemctl enable $app.service --quiet
|
||||||
|
@ -127,15 +57,14 @@ systemctl enable $app.service --quiet
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Integrating service in YunoHost..."
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
yunohost service add $app --log="${log_file}"
|
yunohost service add $app
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# RESTORE THE LOGROTATE CONFIGURATION
|
# RESTORE THE LOGROTATE CONFIGURATION
|
||||||
#=================================================
|
#=================================================
|
||||||
|
ynh_script_progression --message="Setup logging..."
|
||||||
|
|
||||||
mkdir -p "$log_path"
|
myynh_setup_log_file
|
||||||
touch "${log_file}"
|
|
||||||
chown -R "$app:" "$log_path"
|
|
||||||
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
|
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -143,15 +72,8 @@ ynh_restore_file --origin_path="/etc/logrotate.d/$app"
|
||||||
#=================================================
|
#=================================================
|
||||||
# SECURE FILES AND DIRECTORIES
|
# SECURE FILES AND DIRECTORIES
|
||||||
#=================================================
|
#=================================================
|
||||||
|
ynh_script_progression --message="Set file permissions..."
|
||||||
# Set permissions to app files
|
myynh_fix_file_permissions
|
||||||
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
|
# GENERIC FINALIZATION
|
||||||
|
@ -160,7 +82,7 @@ chmod o-rwx "$final_path"
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="start"
|
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# RELOAD NGINX
|
# RELOAD NGINX
|
||||||
|
|
150
scripts/upgrade
150
scripts/upgrade
|
@ -7,68 +7,29 @@
|
||||||
source _common.sh
|
source _common.sh
|
||||||
source /usr/share/yunohost/helpers
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# LOAD SETTINGS
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Loading installation settings..."
|
|
||||||
|
|
||||||
admin=$(ynh_app_setting_get --app="$app" --key=admin)
|
|
||||||
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)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
|
|
||||||
|
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
# config_panel.toml settings:
|
# config_panel.toml settings:
|
||||||
|
|
||||||
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
|
|
||||||
if [ -z "$debug_enabled" ]; then
|
if [ -z "$debug_enabled" ]; then
|
||||||
debug_enabled="0"
|
debug_enabled="0"
|
||||||
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
|
ynh_app_setting_set --app=$app --key=debug_enabled --value="$debug_enabled"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
|
|
||||||
if [ -z "$log_level" ]; then
|
if [ -z "$log_level" ]; then
|
||||||
log_level="WARNING"
|
log_level="WARNING"
|
||||||
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
|
ynh_app_setting_set --app=$app --key=log_level --value="$log_level"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
|
|
||||||
if [ -z "$admin_email" ]; then
|
if [ -z "$admin_email" ]; then
|
||||||
admin_email="${admin}@${domain}"
|
admin_email="${admin}@${domain}"
|
||||||
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
|
ynh_app_setting_set --app=$app --key=admin_email --value="$admin_email"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
|
|
||||||
if [ -z "$default_from_email" ]; then
|
if [ -z "$default_from_email" ]; then
|
||||||
default_from_email="${app}@${domain}"
|
default_from_email="${app}@${domain}"
|
||||||
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
|
ynh_app_setting_set --app=$app --key=default_from_email --value="$default_from_email"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Backing up $app before upgrading (may take a while)..." --weight=40
|
|
||||||
|
|
||||||
# Backup the current version of the app
|
|
||||||
ynh_backup_before_upgrade
|
|
||||||
ynh_clean_setup () {
|
|
||||||
# restore it if the upgrade fails
|
|
||||||
ynh_restore_upgradebackup
|
|
||||||
}
|
|
||||||
# Exit if an error occurs during the execution of the script
|
|
||||||
ynh_abort_if_errors
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# STANDARD UPGRADE STEPS
|
# STANDARD UPGRADE STEPS
|
||||||
#=================================================
|
#=================================================
|
||||||
|
@ -76,91 +37,44 @@ ynh_abort_if_errors
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Stopping systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Stopping systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="stop"
|
ynh_systemd_action --service_name=$app --action="stop" --log_path="$log_file"
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# NGINX CONFIGURATION
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Upgrading nginx web server configuration..."
|
|
||||||
|
|
||||||
# Create a dedicated nginx config
|
|
||||||
# https://yunohost.org/en/contribute/packaging_apps/helpers
|
|
||||||
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
|
|
||||||
ynh_add_nginx_config "public_path" "port"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# SPECIFIC UPGRADE
|
|
||||||
#=================================================
|
|
||||||
# Update dependencies
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Upgrading dependencies..." --weight=20
|
|
||||||
|
|
||||||
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# CREATE DEDICATED USER
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Making sure dedicated system user exists..."
|
|
||||||
|
|
||||||
# Create a system user
|
|
||||||
ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# SETUP SYSTEMD
|
# SETUP SYSTEMD
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_add_systemd_config --service="$app" --template="systemd.service"
|
ynh_add_systemd_config --service=$app --template="systemd.service"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# PYTHON VIRTUALENV
|
# PYTHON VIRTUALENV
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
|
ynh_script_progression --message="Create and setup Python virtualenv..." --weight=45
|
||||||
|
cp ../conf/requirements.txt "$data_dir/requirements.txt"
|
||||||
# Always recreate everything fresh with current python version
|
myynh_setup_python_venv
|
||||||
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"
|
|
||||||
|
|
||||||
cp ../conf/requirements.txt "$final_path/requirements.txt"
|
|
||||||
chown -R "$app:" "$final_path"
|
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# PIP INSTALLATION
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Install project via pip..." --weight=45
|
|
||||||
#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"
|
|
||||||
)
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# copy config files
|
# copy config files
|
||||||
# ================================================
|
# ================================================
|
||||||
ynh_script_progression --message="Create project configuration files..."
|
ynh_script_progression --message="Create project configuration files..."
|
||||||
|
|
||||||
ynh_add_config --template="gunicorn.conf.py" --destination="$final_path/gunicorn.conf.py"
|
ynh_add_config --template="gunicorn.conf.py" --destination="$data_dir/gunicorn.conf.py"
|
||||||
|
|
||||||
ynh_add_config --template="manage.py" --destination="$final_path/manage.py"
|
ynh_add_config --template="manage.py" --destination="$data_dir/manage.py"
|
||||||
chmod +x "$final_path/manage.py"
|
chmod -c +x "$data_dir/manage.py"
|
||||||
|
|
||||||
ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
|
ynh_add_config --template="settings.py" --destination="$data_dir/settings.py"
|
||||||
ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
|
ynh_add_config --template="setup_user.py" --destination="$data_dir/setup_user.py"
|
||||||
ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
|
ynh_add_config --template="urls.py" --destination="$data_dir/urls.py"
|
||||||
ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py"
|
ynh_add_config --template="wsgi.py" --destination="$data_dir/wsgi.py"
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# MIGRATE PYINVENTORY
|
# MIGRATE PYINVENTORY
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
||||||
|
|
||||||
cd "$final_path" || exit
|
cd "$data_dir" || exit
|
||||||
|
|
||||||
# Just for debugging:
|
# Just for debugging:
|
||||||
./manage.py diffsettings
|
./manage.py diffsettings
|
||||||
|
@ -182,43 +96,23 @@ cd "$final_path" || exit
|
||||||
ynh_script_progression --message="Upgrading logrotate configuration..."
|
ynh_script_progression --message="Upgrading logrotate configuration..."
|
||||||
|
|
||||||
# Use logrotate to manage app-specific logfile(s)
|
# Use logrotate to manage app-specific logfile(s)
|
||||||
ynh_use_logrotate --non-append
|
ynh_use_logrotate --logfile="$log_file" --specific_user=$app --non-append
|
||||||
|
|
||||||
#=================================================
|
|
||||||
# INTEGRATE SERVICE IN YUNOHOST
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Integrating service in YunoHost..."
|
|
||||||
|
|
||||||
yunohost service add $app --log="${log_file}"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# GENERIC FINALIZATION
|
# GENERIC FINALIZATION
|
||||||
#=================================================
|
#=================================================
|
||||||
# SECURE FILES AND DIRECTORIES
|
# SECURE FILES AND DIRECTORIES
|
||||||
#=================================================
|
#=================================================
|
||||||
|
ynh_script_progression --message="Set file permissions..."
|
||||||
# Set permissions to app files
|
myynh_fix_file_permissions
|
||||||
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"
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# Start the app server via systemd
|
# Start the app server via systemd
|
||||||
#=================================================
|
#=================================================
|
||||||
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
|
||||||
|
|
||||||
ynh_systemd_action --service_name="$app" --action="start"
|
yunohost service add $app
|
||||||
|
ynh_systemd_action --service_name=$app --action="start" --log_path="$log_file"
|
||||||
#=================================================
|
|
||||||
# RELOAD NGINX
|
|
||||||
#=================================================
|
|
||||||
ynh_script_progression --message="Reloading nginx web server..."
|
|
||||||
|
|
||||||
ynh_systemd_action --service_name=nginx --action=reload
|
|
||||||
|
|
||||||
#=================================================
|
#=================================================
|
||||||
# END OF SCRIPT
|
# END OF SCRIPT
|
||||||
|
|
31
tests.toml
Normal file
31
tests.toml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
test_format = 1.0
|
||||||
|
|
||||||
|
[default]
|
||||||
|
|
||||||
|
# ------------
|
||||||
|
# Tests to run
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
# NB: the tests to run are automatically deduced by the CI script according to the
|
||||||
|
# content of the app's manifest. The declarations below allow to customize which
|
||||||
|
# tests are ran, possibly add special test suite to test special args, or
|
||||||
|
# declare which commits to test upgrade from.
|
||||||
|
#
|
||||||
|
# You can also decide (though this is discouraged!) to ban/ignore some tests,
|
||||||
|
|
||||||
|
# The test IDs to be used in only/exclude statements are:
|
||||||
|
# install.root, install.subdir, install.nourl, install.multi, backup_restore, upgrade, upgrade.someCommitId change_url
|
||||||
|
#exclude = ["install.private", "install.multi"]
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Default args to use for install
|
||||||
|
# -------------------------------
|
||||||
|
|
||||||
|
# By default, the CI will automagically fill the 'standard' args
|
||||||
|
# such as domain, path, admin, is_public and password with relevant values
|
||||||
|
# and also install args with a "default" provided in the manifest..
|
||||||
|
# It should only make sense to declare custom args here for args with no default values
|
||||||
|
|
||||||
|
args.default_from_email = "default_from_email@example.tld"
|
||||||
|
args.admin_email = "admin_email@example.tld"
|
||||||
|
|
|
@ -11,7 +11,7 @@ import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django_yunohost_integration.local_test import create_local_test
|
from django_yunohost_integration.local_test import CreateResults, create_local_test
|
||||||
|
|
||||||
|
|
||||||
BASE_PATH = Path(__file__).parent.parent
|
BASE_PATH = Path(__file__).parent.parent
|
||||||
|
@ -21,23 +21,23 @@ os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||||
|
|
||||||
def pytest_configure():
|
def pytest_configure():
|
||||||
print('Compile YunoHost files...')
|
print('Compile YunoHost files...')
|
||||||
final_path = create_local_test(
|
result: CreateResults = create_local_test(
|
||||||
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
|
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
|
||||||
destination=BASE_PATH / 'local_test',
|
destination=BASE_PATH / 'local_test',
|
||||||
runserver=False,
|
runserver=False,
|
||||||
extra_replacements={
|
extra_replacements={
|
||||||
'__DEBUG_ENABLED__': '0',
|
'__DEBUG_ENABLED__': 'NO', # "YES" or "NO" string
|
||||||
'__LOG_LEVEL__': 'INFO',
|
'__LOG_LEVEL__': 'INFO',
|
||||||
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
|
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
|
||||||
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
|
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
print('Local test files created here:')
|
print('Local test files created:')
|
||||||
print(f'"{final_path}"')
|
print(result)
|
||||||
|
|
||||||
os.chdir(final_path)
|
os.chdir(result.data_dir_path)
|
||||||
final_home_str = str(final_path)
|
data_dir = str(result.data_dir_path)
|
||||||
if final_home_str not in sys.path:
|
if data_dir not in sys.path:
|
||||||
sys.path.insert(0, final_home_str)
|
sys.path.insert(0, data_dir)
|
||||||
|
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
|
@ -27,16 +27,16 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
|
||||||
|
|
||||||
assert settings.PATH_URL == 'app_path'
|
assert settings.PATH_URL == 'app_path'
|
||||||
|
|
||||||
assert str(settings.FINALPATH).endswith('/local_test/opt_yunohost')
|
assert str(settings.DATA_DIR_PATH).endswith('/local_test/opt_yunohost')
|
||||||
assert str(settings.PUBLIC_PATH).endswith('/local_test/var_www')
|
assert str(settings.INSTALL_DIR_PATH).endswith('/local_test/var_www')
|
||||||
assert str(settings.LOG_FILE).endswith('/local_test/var_log_pyinventory.log')
|
assert str(settings.LOG_FILE_PATH).endswith('/local_test/var_log_pyinventory.log')
|
||||||
|
|
||||||
assert settings.ROOT_URLCONF == 'urls'
|
assert settings.ROOT_URLCONF == 'urls'
|
||||||
assert reverse('admin:index') == '/app_path/'
|
assert reverse('admin:index') == '/app_path/'
|
||||||
|
|
||||||
def test_config_panel_settings(self):
|
def test_config_panel_settings(self):
|
||||||
# config_panel.toml settings, set via tests.conftest.pytest_configure():
|
# config_panel.toml settings, set via tests.conftest.pytest_configure():
|
||||||
assert settings.DEBUG_ENABLED == '0' and settings.DEBUG is False
|
assert settings.DEBUG_ENABLED == 'NO' and settings.DEBUG is False
|
||||||
assert settings.LOG_LEVEL == 'INFO'
|
assert settings.LOG_LEVEL == 'INFO'
|
||||||
assert settings.ADMIN_EMAIL == 'foo-bar@test.tld'
|
assert settings.ADMIN_EMAIL == 'foo-bar@test.tld'
|
||||||
assert settings.DEFAULT_FROM_EMAIL == 'django_app@test.tld'
|
assert settings.DEFAULT_FROM_EMAIL == 'django_app@test.tld'
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div id="branding">
|
<div id="branding">
|
||||||
<h1 id="site-name">
|
<h1 id="site-name">
|
||||||
<a href="/app_path/">
|
<a href="/app_path/">
|
||||||
PyInventory v0.19.2
|
PyInventory v0.19.3
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,11 +28,34 @@
|
||||||
Log out
|
Log out
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
<button class="theme-toggle">
|
||||||
|
<div class="visually-hidden theme-label-when-auto">
|
||||||
|
Toggle theme (current theme: auto)
|
||||||
|
</div>
|
||||||
|
<div class="visually-hidden theme-label-when-light">
|
||||||
|
Toggle theme (current theme: light)
|
||||||
|
</div>
|
||||||
|
<div class="visually-hidden theme-label-when-dark">
|
||||||
|
Toggle theme (current theme: dark)
|
||||||
|
</div>
|
||||||
|
<svg aria-hidden="true" class="theme-icon-when-auto">
|
||||||
|
<use xlink:href="#icon-auto">
|
||||||
|
</use>
|
||||||
|
</svg>
|
||||||
|
<svg aria-hidden="true" class="theme-icon-when-dark">
|
||||||
|
<use xlink:href="#icon-moon">
|
||||||
|
</use>
|
||||||
|
</svg>
|
||||||
|
<svg aria-hidden="true" class="theme-icon-when-light">
|
||||||
|
<use xlink:href="#icon-sun">
|
||||||
|
</use>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- END Header -->
|
<!-- END Header -->
|
||||||
<div class="main" id="main">
|
<div class="main" id="main">
|
||||||
<div class="content">
|
<div class="content" id="content-start" tabindex="-1">
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<div class="colMS" id="content">
|
<div class="colMS" id="content">
|
||||||
<h1>
|
<h1>
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import difflib
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
|
@ -16,7 +13,8 @@ from bx_py_utils.path import assert_is_dir, assert_is_file
|
||||||
from django_tools.unittest_utils.project_setup import check_editor_config
|
from django_tools.unittest_utils.project_setup import check_editor_config
|
||||||
from django_yunohost_integration.test_utils import assert_project_version
|
from django_yunohost_integration.test_utils import assert_project_version
|
||||||
|
|
||||||
from inventory import __version__
|
from inventory import __version__ as inventory_version
|
||||||
|
from pyinventory_ynh import __version__ as pyinventory_ynh_version
|
||||||
|
|
||||||
|
|
||||||
PACKAGE_ROOT = Path(__file__).parent.parent
|
PACKAGE_ROOT = Path(__file__).parent.parent
|
||||||
|
@ -31,68 +29,25 @@ def assert_file_contains_string(file_path, string):
|
||||||
|
|
||||||
|
|
||||||
def test_version():
|
def test_version():
|
||||||
if 'GITHUB_ACTION' not in os.environ:
|
assert inventory_version in pyinventory_ynh_version, f'{inventory_version!r} not in {pyinventory_ynh_version!r}'
|
||||||
# Github has a rate-limiting... So don't fetch the API if we run as GitHub action
|
|
||||||
assert_project_version(
|
|
||||||
current_version=__version__,
|
|
||||||
github_project_url='https://github.com/jedie/PyInventory',
|
|
||||||
)
|
|
||||||
|
|
||||||
pyproject_toml_path = Path(PACKAGE_ROOT, 'pyproject.toml')
|
assert '+ynh' in pyinventory_ynh_version, f'{pyinventory_ynh_version!r} does not contain "+ynh"'
|
||||||
pyproject_toml = tomllib.loads(pyproject_toml_path.read_text(encoding='UTF-8'))
|
|
||||||
pyproject_version = pyproject_toml['tool']['poetry']['version']
|
|
||||||
assert pyproject_version.startswith(
|
|
||||||
f'{__version__}+ynh'
|
|
||||||
), f'{pyproject_version!r} does not start with "{__version__}+ynh"'
|
|
||||||
|
|
||||||
# pyproject.toml needs a PEP 440 conform version and used "+ynh"
|
# pyproject.toml needs a PEP 440 conform version and used "+ynh"
|
||||||
# the YunoHost syntax is: "~ynh", just "convert this:
|
# the YunoHost syntax is: "~ynh", just "convert this:
|
||||||
manifest_version = pyproject_version.replace('+', '~')
|
manifest_version = pyinventory_ynh_version.replace('+', '~')
|
||||||
|
|
||||||
assert_file_contains_string(
|
assert_file_contains_string(
|
||||||
file_path=Path(PACKAGE_ROOT, 'manifest.json'),
|
file_path=Path(PACKAGE_ROOT, 'manifest.toml'),
|
||||||
string=f'"version": "{manifest_version}"',
|
string=f'version = "{manifest_version}"',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if 'GITHUB_ACTION' not in os.environ:
|
||||||
def poetry_check_output(*args):
|
# Github has a rate-limiting... So don't fetch the API if we run as GitHub action
|
||||||
poerty_bin = shutil.which('poetry')
|
assert_project_version(
|
||||||
|
current_version=inventory_version,
|
||||||
output = subprocess.check_output(
|
github_project_url='https://github.com/jedie/PyInventory',
|
||||||
(poerty_bin,) + args,
|
|
||||||
text=True,
|
|
||||||
env=os.environ,
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
cwd=str(PACKAGE_ROOT),
|
|
||||||
)
|
|
||||||
print(output)
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
def test_poetry_check():
|
|
||||||
output = poetry_check_output('check')
|
|
||||||
assert output == 'All set!\n'
|
|
||||||
|
|
||||||
|
|
||||||
def test_requirements_txt():
|
|
||||||
requirements_txt = PACKAGE_ROOT / 'conf' / 'requirements.txt'
|
|
||||||
assert_is_file(requirements_txt)
|
|
||||||
|
|
||||||
output = poetry_check_output('export', '-f', 'requirements.txt')
|
|
||||||
assert 'Warning' not in output
|
|
||||||
|
|
||||||
current_content = requirements_txt.read_text()
|
|
||||||
|
|
||||||
diff = '\n'.join(
|
|
||||||
difflib.unified_diff(
|
|
||||||
current_content.splitlines(),
|
|
||||||
output.splitlines(),
|
|
||||||
fromfile=str(requirements_txt),
|
|
||||||
tofile='FRESH EXPORT',
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
print(diff)
|
|
||||||
assert diff == '', f'{requirements_txt} is not up-to-date! (Hint: call: "make update")'
|
|
||||||
|
|
||||||
|
|
||||||
def test_screenshot_filenames():
|
def test_screenshot_filenames():
|
||||||
|
@ -118,40 +73,36 @@ def test_check_editor_config():
|
||||||
check_editor_config(package_root=PACKAGE_ROOT)
|
check_editor_config(package_root=PACKAGE_ROOT)
|
||||||
|
|
||||||
|
|
||||||
def _call_make(*args):
|
class ManifestTestCase(TestCase):
|
||||||
make_bin = shutil.which('make')
|
def test_manifest_toml(self):
|
||||||
assert make_bin
|
manifest_path = PACKAGE_ROOT / 'manifest.toml'
|
||||||
return subprocess.check_output(
|
assert_is_file(manifest_path)
|
||||||
(make_bin,) + args,
|
|
||||||
text=True,
|
|
||||||
env=dict(PATH=os.environ['PATH']),
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
cwd=str(PACKAGE_ROOT),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
cfg = tomllib.loads(manifest_path.read_text(encoding='UTF-8'))
|
||||||
|
|
||||||
def test_check_code_style():
|
self.assertEqual(cfg['packaging_format'], 2)
|
||||||
# First try:
|
|
||||||
try:
|
|
||||||
_call_make('lint')
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
# Fix and test again:
|
|
||||||
try:
|
|
||||||
_call_make('fix-code-style')
|
|
||||||
_call_make('lint')
|
|
||||||
except subprocess.CalledProcessError as err:
|
|
||||||
raise AssertionError(f'Linting error:\n{"-"*100}\n{err.stdout}\n{"-"*100}')
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigPanelTestCase(TestCase):
|
|
||||||
def test_config_panel_toml(self):
|
|
||||||
config_panel_path = PACKAGE_ROOT / 'config_panel.toml'
|
|
||||||
assert_is_file(config_panel_path)
|
|
||||||
|
|
||||||
cfg = tomllib.loads(config_panel_path.read_text(encoding='UTF-8'))
|
|
||||||
|
|
||||||
self.assertEqual(cfg['version'], '1.0')
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(cfg['main']['config'].keys()),
|
set(cfg['install'].keys()),
|
||||||
{'name', 'default_from_email', 'admin_email', 'debug_enabled', 'log_level'},
|
{
|
||||||
|
'admin',
|
||||||
|
'admin_email',
|
||||||
|
'debug_enabled',
|
||||||
|
'default_from_email',
|
||||||
|
'domain',
|
||||||
|
'init_main_permission',
|
||||||
|
'log_level',
|
||||||
|
'path',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
set(cfg['resources'].keys()),
|
||||||
|
{
|
||||||
|
'apt',
|
||||||
|
'data_dir',
|
||||||
|
'database',
|
||||||
|
'install_dir',
|
||||||
|
'permissions',
|
||||||
|
'ports',
|
||||||
|
'system_user',
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue