mirror of
https://github.com/YunoHost-Apps/django-fmd_ynh.git
synced 2024-09-03 18:26:27 +02:00
init
This commit is contained in:
parent
fc0da1871d
commit
423672a0df
38 changed files with 4068 additions and 6 deletions
21
.editorconfig
Normal file
21
.editorconfig
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
line_length = 119
|
||||||
|
|
||||||
|
[{Makefile,**.mk}]
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = false
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
7
.flake8
Normal file
7
.flake8
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# Move to pyproject.toml after: https://gitlab.com/pycqa/flake8/-/issues/428
|
||||||
|
#
|
||||||
|
[flake8]
|
||||||
|
exclude = .pytest_cache, .tox, dist, htmlcov, local_test
|
||||||
|
ignore = F405
|
||||||
|
max-line-length = 119
|
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.*
|
||||||
|
!.github
|
||||||
|
!.editorconfig
|
||||||
|
!.flake8
|
||||||
|
!.gitignore
|
||||||
|
__pycache__
|
||||||
|
secret.txt
|
||||||
|
/local_test/
|
||||||
|
/coverage.xml
|
||||||
|
/htmlcov/
|
8
LICENSE
8
LICENSE
|
@ -1,7 +1,7 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
<https://www.gnu.org/licenses/>.
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
The GNU General Public License does not permit incorporating your program
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
may consider it more useful to permit linking proprietary applications with
|
may consider it more useful to permit linking proprietary applications with
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License. But first, please read
|
Public License instead of this License. But first, please read
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
|
|
59
Makefile
Normal file
59
Makefile
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
SHELL := /bin/bash
|
||||||
|
MAX_LINE_LENGTH := 119
|
||||||
|
|
||||||
|
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-poetry: ## install or update poetry
|
||||||
|
pip3 install -U pip
|
||||||
|
pip3 install -U poetry
|
||||||
|
|
||||||
|
install: check-poetry ## install project via poetry
|
||||||
|
poetry install
|
||||||
|
|
||||||
|
update: install-poetry ## update the sources and installation and generate "conf/requirements.txt"
|
||||||
|
poetry run pip install -U pip
|
||||||
|
poetry update
|
||||||
|
poetry export -f requirements.txt --output conf/requirements.txt
|
||||||
|
|
||||||
|
lint: ## Run code formatters and linter
|
||||||
|
poetry run flynt --fail-on-change --line-length=${MAX_LINE_LENGTH} .
|
||||||
|
poetry run isort --check-only .
|
||||||
|
poetry run flake8 .
|
||||||
|
|
||||||
|
fix-code-style: ## Fix code formatting
|
||||||
|
poetry run flynt --line-length=${MAX_LINE_LENGTH} .
|
||||||
|
poetry run black --verbose --safe --line-length=${MAX_LINE_LENGTH} --skip-string-normalization .
|
||||||
|
poetry run isort .
|
||||||
|
|
||||||
|
tox-listenvs: check-poetry ## List all tox test environments
|
||||||
|
poetry run tox --listenvs
|
||||||
|
|
||||||
|
tox: check-poetry ## Run pytest via tox with all environments
|
||||||
|
poetry run tox
|
||||||
|
|
||||||
|
pytest: install ## Run pytest
|
||||||
|
poetry run python3 ./run_pytest.py
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
.PHONY: help check-poetry install-poetry install update local-test
|
194
README.md
194
README.md
|
@ -1,2 +1,192 @@
|
||||||
# django-fmd_ynh
|
<!--
|
||||||
Find My Device Server -> https://gitlab.com/jedie/django-find-my-device
|
N.B.: This README was automatically generated by https://github.com/YunoHost/apps/tree/master/tools/README-generator
|
||||||
|
It shall NOT be edited by hand.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# django-fmd for YunoHost
|
||||||
|
|
||||||
|
[![Integration level](https://dash.yunohost.org/integration/django-fmd.svg)](https://dash.yunohost.org/appci/app/django-fmd) ![](https://ci-apps.yunohost.org/ci/badges/django-fmd.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django-fmd.maintain.svg)
|
||||||
|
[![Install django-fmd with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-fmd)
|
||||||
|
|
||||||
|
*[Lire ce readme en français.](./README_fr.md)*
|
||||||
|
|
||||||
|
> *This package allows you to install django-fmd quickly and simply on a YunoHost server.
|
||||||
|
If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.*
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Web based FritzBox management using Python/Django and the great [fritzconnection](https://github.com/kbr/fritzconnection) library.
|
||||||
|
|
||||||
|
The basic idea is to block/unblock Internet access to a group of devices as easily as possible.
|
||||||
|
|
||||||
|
|
||||||
|
[![pytest](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh)
|
||||||
|
|
||||||
|
![django-fmd @ PyPi](https://img.shields.io/pypi/v/django-fmd?label=django-fmd%20%40%20PyPi)
|
||||||
|
![Python Versions](https://img.shields.io/pypi/pyversions/django-fmd)
|
||||||
|
![License GPL V3+](https://img.shields.io/pypi/l/django-fmd)
|
||||||
|
|
||||||
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
|
||||||
|
|
||||||
|
|
||||||
|
**Shipped version:** 0.2.0~ynh1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
![](./doc/screenshots/v002_hosts_change_list.png)
|
||||||
|
![](./doc/screenshots/v010rc1_group_management.png)
|
||||||
|
|
||||||
|
## Disclaimers / important information
|
||||||
|
|
||||||
|
## Settings and upgrades
|
||||||
|
|
||||||
|
Almost everything related to django-fmd's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
|
You can edit the file `/opt/yunohost/django-fmd/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
|
Test sending emails:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh admin@yourdomain.tld
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
||||||
|
To check current ADMINS run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
If you prefere to send error emails to a extrnal email address, just do something like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/django-fmd/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
To check the effective settings, run this:
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./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
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Yunohost developer commands
|
||||||
|
|
||||||
|
To remove call e.g.:
|
||||||
|
```bash
|
||||||
|
sudo yunohost app remove django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Backup / remove / restore cycle, e.g.:
|
||||||
|
```bash
|
||||||
|
yunohost backup create --apps django-fmd
|
||||||
|
yunohost backup list
|
||||||
|
archives:
|
||||||
|
- django-fmd-pre-upgrade1
|
||||||
|
- 20201223-163434
|
||||||
|
yunohost app remove django-fmd
|
||||||
|
yunohost backup restore 20201223-163434 --apps django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Debug installation, e.g.:
|
||||||
|
```bash
|
||||||
|
root@yunohost:~# ls -la /var/www/django-fmd/
|
||||||
|
total 18
|
||||||
|
drwxr-xr-x 4 root root 4 Dec 8 08:36 .
|
||||||
|
drwxr-xr-x 6 root root 6 Dec 8 08:36 ..
|
||||||
|
drwxr-xr-x 2 root root 2 Dec 8 08:36 media
|
||||||
|
drwxr-xr-x 7 root root 8 Dec 8 08:40 static
|
||||||
|
|
||||||
|
root@yunohost:~# ls -la /opt/yunohost/django-fmd/
|
||||||
|
total 58
|
||||||
|
drwxr-xr-x 5 django-fmd django-fmd 11 Dec 8 08:39 .
|
||||||
|
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 460 Dec 8 08:39 gunicorn.conf.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 0 Dec 8 08:39 local_settings.py
|
||||||
|
-rwxr-xr-x 1 django-fmd django-fmd 274 Dec 8 08:39 manage.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 171 Dec 8 08:39 secret.txt
|
||||||
|
drwxr-xr-x 6 django-fmd django-fmd 6 Dec 8 08:37 venv
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 115 Dec 8 08:39 wsgi.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 4737 Dec 8 08:39 settings.py
|
||||||
|
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py check
|
||||||
|
django-fmd v0.8.2 (Django v2.2.17)
|
||||||
|
DJANGO_SETTINGS_MODULE='settings'
|
||||||
|
PROJECT_PATH:/opt/yunohost/django-fmd/venv/lib/python3.7/site-packages
|
||||||
|
BASE_PATH:/opt/yunohost/django-fmd
|
||||||
|
System check identified no issues (0 silenced).
|
||||||
|
|
||||||
|
root@yunohost:~# tail -f /var/log/django-fmd/django-fmd.log
|
||||||
|
root@yunohost:~# cat /etc/systemd/system/django-fmd.service
|
||||||
|
|
||||||
|
root@yunohost:~# systemctl reload-or-restart django-fmd
|
||||||
|
root@yunohost:~# journalctl --unit=django-fmd --follow
|
||||||
|
```
|
||||||
|
|
||||||
|
## local test
|
||||||
|
|
||||||
|
For quicker developing of django-fmd in the context of YunoHost app,
|
||||||
|
it's possible to run the Django developer server with the settings
|
||||||
|
and urls made for YunoHost installation.
|
||||||
|
|
||||||
|
e.g.:
|
||||||
|
```bash
|
||||||
|
~$ git clone https://github.com/YunoHost-Apps/django-fmd_ynh.git
|
||||||
|
~$ cd django-fmd_ynh/
|
||||||
|
~/django-fmd_ynh$ make
|
||||||
|
install-poetry install or update poetry
|
||||||
|
install install django-fmd via poetry
|
||||||
|
update update the sources and installation
|
||||||
|
local-test Run local_test.py to run django-fmd_ynh locally
|
||||||
|
~/django-fmd_ynh$ make install-poetry
|
||||||
|
~/django-fmd_ynh$ make install
|
||||||
|
~/django-fmd_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
|
||||||
|
|
||||||
|
* Official app website: https://gitlab.com/jedie/django-find-my-device
|
||||||
|
* Upstream app code repository: https://gitlab.com/jedie/django-find-my-device
|
||||||
|
* YunoHost documentation for this app: https://yunohost.org/app_django-fmd
|
||||||
|
* Report a bug: https://github.com/YunoHost-Apps/django-fmd_ynh/issues
|
||||||
|
|
||||||
|
## Developer info
|
||||||
|
|
||||||
|
Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing).
|
||||||
|
|
||||||
|
To try the testing branch, please proceed like that.
|
||||||
|
```
|
||||||
|
sudo yunohost app install https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing --debug
|
||||||
|
or
|
||||||
|
sudo yunohost app upgrade django-fmd -u https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**More info regarding app packaging:** https://yunohost.org/packaging_apps
|
||||||
|
|
188
README_fr.md
Normal file
188
README_fr.md
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
# django-fmd pour YunoHost
|
||||||
|
|
||||||
|
[![Niveau d'intégration](https://dash.yunohost.org/integration/django-fmd.svg)](https://dash.yunohost.org/appci/app/django-fmd) ![](https://ci-apps.yunohost.org/ci/badges/django-fmd.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django-fmd.maintain.svg)
|
||||||
|
[![Installer django-fmd avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-fmd)
|
||||||
|
|
||||||
|
*[Read this readme in english.](./README.md)*
|
||||||
|
*[Lire ce readme en français.](./README_fr.md)*
|
||||||
|
|
||||||
|
> *Ce package vous permet d'installer django-fmd rapidement et simplement sur un serveur YunoHost.
|
||||||
|
Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.*
|
||||||
|
|
||||||
|
## Vue d'ensemble
|
||||||
|
|
||||||
|
Web based FritzBox management using Python/Django and the great [fritzconnection](https://github.com/kbr/fritzconnection) library.
|
||||||
|
|
||||||
|
The basic idea is to block/unblock Internet access to a group of devices as easily as possible.
|
||||||
|
|
||||||
|
|
||||||
|
[![pytest](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh)
|
||||||
|
|
||||||
|
![django-fmd @ PyPi](https://img.shields.io/pypi/v/django-fmd?label=django-fmd%20%40%20PyPi)
|
||||||
|
![Python Versions](https://img.shields.io/pypi/pyversions/django-fmd)
|
||||||
|
![License GPL V3+](https://img.shields.io/pypi/l/django-fmd)
|
||||||
|
|
||||||
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
|
||||||
|
|
||||||
|
|
||||||
|
**Version incluse :** 0.2.0~ynh1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Captures d'écran
|
||||||
|
|
||||||
|
![](./doc/screenshots/v002_hosts_change_list.png)
|
||||||
|
![](./doc/screenshots/v010rc1_group_management.png)
|
||||||
|
|
||||||
|
## Avertissements / informations importantes
|
||||||
|
|
||||||
|
## Settings and upgrades
|
||||||
|
|
||||||
|
Almost everything related to django-fmd's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
|
You can edit the file `/opt/yunohost/django-fmd/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
|
Test sending emails:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh admin@yourdomain.tld
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
||||||
|
To check current ADMINS run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
If you prefere to send error emails to a extrnal email address, just do something like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/django-fmd/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
To check the effective settings, run this:
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./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
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Yunohost developer commands
|
||||||
|
|
||||||
|
To remove call e.g.:
|
||||||
|
```bash
|
||||||
|
sudo yunohost app remove django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Backup / remove / restore cycle, e.g.:
|
||||||
|
```bash
|
||||||
|
yunohost backup create --apps django-fmd
|
||||||
|
yunohost backup list
|
||||||
|
archives:
|
||||||
|
- django-fmd-pre-upgrade1
|
||||||
|
- 20201223-163434
|
||||||
|
yunohost app remove django-fmd
|
||||||
|
yunohost backup restore 20201223-163434 --apps django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Debug installation, e.g.:
|
||||||
|
```bash
|
||||||
|
root@yunohost:~# ls -la /var/www/django-fmd/
|
||||||
|
total 18
|
||||||
|
drwxr-xr-x 4 root root 4 Dec 8 08:36 .
|
||||||
|
drwxr-xr-x 6 root root 6 Dec 8 08:36 ..
|
||||||
|
drwxr-xr-x 2 root root 2 Dec 8 08:36 media
|
||||||
|
drwxr-xr-x 7 root root 8 Dec 8 08:40 static
|
||||||
|
|
||||||
|
root@yunohost:~# ls -la /opt/yunohost/django-fmd/
|
||||||
|
total 58
|
||||||
|
drwxr-xr-x 5 django-fmd django-fmd 11 Dec 8 08:39 .
|
||||||
|
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 460 Dec 8 08:39 gunicorn.conf.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 0 Dec 8 08:39 local_settings.py
|
||||||
|
-rwxr-xr-x 1 django-fmd django-fmd 274 Dec 8 08:39 manage.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 171 Dec 8 08:39 secret.txt
|
||||||
|
drwxr-xr-x 6 django-fmd django-fmd 6 Dec 8 08:37 venv
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 115 Dec 8 08:39 wsgi.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 4737 Dec 8 08:39 settings.py
|
||||||
|
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py check
|
||||||
|
django-fmd v0.8.2 (Django v2.2.17)
|
||||||
|
DJANGO_SETTINGS_MODULE='settings'
|
||||||
|
PROJECT_PATH:/opt/yunohost/django-fmd/venv/lib/python3.7/site-packages
|
||||||
|
BASE_PATH:/opt/yunohost/django-fmd
|
||||||
|
System check identified no issues (0 silenced).
|
||||||
|
|
||||||
|
root@yunohost:~# tail -f /var/log/django-fmd/django-fmd.log
|
||||||
|
root@yunohost:~# cat /etc/systemd/system/django-fmd.service
|
||||||
|
|
||||||
|
root@yunohost:~# systemctl reload-or-restart django-fmd
|
||||||
|
root@yunohost:~# journalctl --unit=django-fmd --follow
|
||||||
|
```
|
||||||
|
|
||||||
|
## local test
|
||||||
|
|
||||||
|
For quicker developing of django-fmd in the context of YunoHost app,
|
||||||
|
it's possible to run the Django developer server with the settings
|
||||||
|
and urls made for YunoHost installation.
|
||||||
|
|
||||||
|
e.g.:
|
||||||
|
```bash
|
||||||
|
~$ git clone https://github.com/YunoHost-Apps/django-fmd_ynh.git
|
||||||
|
~$ cd django-fmd_ynh/
|
||||||
|
~/django-fmd_ynh$ make
|
||||||
|
install-poetry install or update poetry
|
||||||
|
install install django-fmd via poetry
|
||||||
|
update update the sources and installation
|
||||||
|
local-test Run local_test.py to run django-fmd_ynh locally
|
||||||
|
~/django-fmd_ynh$ make install-poetry
|
||||||
|
~/django-fmd_ynh$ make install
|
||||||
|
~/django-fmd_ynh$ make local-test
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* SQlite database will be used
|
||||||
|
* A super user with username `test` and password `test` is created
|
||||||
|
* The page is available under `http://127.0.0.1:8000/app_path/`
|
||||||
|
|
||||||
|
## Documentations et ressources
|
||||||
|
|
||||||
|
* Site officiel de l'app : https://gitlab.com/jedie/django-find-my-device
|
||||||
|
* Dépôt de code officiel de l'app : https://gitlab.com/jedie/django-find-my-device
|
||||||
|
* Documentation YunoHost pour cette app : https://yunohost.org/app_django-fmd
|
||||||
|
* Signaler un bug : https://github.com/YunoHost-Apps/django-fmd_ynh/issues
|
||||||
|
|
||||||
|
## Informations pour les développeurs
|
||||||
|
|
||||||
|
Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing).
|
||||||
|
|
||||||
|
Pour essayer la branche testing, procédez comme suit.
|
||||||
|
```
|
||||||
|
sudo yunohost app install https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing --debug
|
||||||
|
ou
|
||||||
|
sudo yunohost app upgrade django-fmd -u https://github.com/YunoHost-Apps/django-fmd_ynh/tree/testing --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps
|
33
check_process
Normal file
33
check_process
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# 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=1
|
||||||
|
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
conf/django-fmd.service
Normal file
17
conf/django-fmd.service
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[Unit]
|
||||||
|
Description=django-fmd application server
|
||||||
|
After=redis.service postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=__APP__
|
||||||
|
Group=__APP__
|
||||||
|
WorkingDirectory=__FINALPATH__/
|
||||||
|
|
||||||
|
ExecStart=__FINALPATH__/venv/bin/gunicorn --config __FINALPATH__/gunicorn.conf.py wsgi
|
||||||
|
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
SyslogIdentifier=__APP__-server
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
20
conf/gunicorn.conf.py
Normal file
20
conf/gunicorn.conf.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
"""
|
||||||
|
Configuration for Gunicorn
|
||||||
|
"""
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
|
|
||||||
|
bind = '127.0.0.1:__PORT__'
|
||||||
|
|
||||||
|
# https://docs.gunicorn.org/en/latest/settings.html#workers
|
||||||
|
workers = multiprocessing.cpu_count() * 2 + 1
|
||||||
|
|
||||||
|
# https://docs.gunicorn.org/en/latest/settings.html#logging
|
||||||
|
loglevel = 'info'
|
||||||
|
|
||||||
|
# https://docs.gunicorn.org/en/latest/settings.html#logging
|
||||||
|
accesslog = '__LOG_FILE__'
|
||||||
|
errorlog = '__LOG_FILE__'
|
||||||
|
|
||||||
|
# https://docs.gunicorn.org/en/latest/settings.html#pidfile
|
||||||
|
pidfile = '__FINAL_HOME_PATH__/gunicorn.pid'
|
8
conf/local_settings.py
Normal file
8
conf/local_settings.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
"""
|
||||||
|
Here it's possible to overwrite everything in settings.py
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Used for YunoHost config and will be **overwritten** on every config change!
|
||||||
|
"""
|
||||||
|
|
||||||
|
DEBUG = __DJANGO_DEBUG__ # Don't turn DEBUG on in production!
|
15
conf/manage.py
Executable file
15
conf/manage.py
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!__FINAL_HOME_PATH__/venv/bin/python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
34
conf/nginx.conf
Normal file
34
conf/nginx.conf
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
location __PATH__/static/ {
|
||||||
|
# Django static files
|
||||||
|
alias __PUBLIC_PATH__/static/;
|
||||||
|
expires 30d;
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: django-sendfile2:
|
||||||
|
#location __PATH__/media/ {
|
||||||
|
# # DATA_DIR/media/
|
||||||
|
# alias __PUBLIC_PATH__/media/;
|
||||||
|
# expires 30d;
|
||||||
|
#}
|
||||||
|
|
||||||
|
location __PATH__/ {
|
||||||
|
# https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
|
||||||
|
|
||||||
|
# this is needed if you have file import via upload enabled
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Scheme $scheme;
|
||||||
|
|
||||||
|
proxy_read_timeout 30;
|
||||||
|
proxy_send_timeout 30;
|
||||||
|
proxy_connect_timeout 30;
|
||||||
|
proxy_redirect off;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:__PORT__;
|
||||||
|
}
|
166
conf/requirements.txt
Normal file
166
conf/requirements.txt
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
asgiref==3.5.2; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:1d2880b792ae8757289136f1db2b7b99100ce959b2aa57fd69dab783d05afac4 \
|
||||||
|
--hash=sha256:4a29362a6acebe09bf1d6640db38c1dc3d9217c68e6f9f6204d72667fc19a424
|
||||||
|
async-timeout==4.0.2; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15 \
|
||||||
|
--hash=sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c
|
||||||
|
bleach==5.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a \
|
||||||
|
--hash=sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c
|
||||||
|
bx-django-utils==26; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:c04776c4c6b275ddcadae79fd1578e6ae9ba92d8cf752a9ee4f2b70a22f4236e \
|
||||||
|
--hash=sha256:19349d0a8fa165d87b4fd544efb61418f7d6c41cfabaa46d0153bb6d844262a1
|
||||||
|
bx-py-utils==66; python_version >= "3.6" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:00ab6dfc063e8431d195c71c43e1063e3e28790205324fe4ceca676a11fd281a \
|
||||||
|
--hash=sha256:c6a9f4f11e3465de676f09f2c6bd888afa6d8ab23a030e1bd9ff2a1697fddcf2
|
||||||
|
colorama==0.4.5; python_version >= "3.7" and python_full_version < "3.0.0" and sys_platform == "win32" or python_version >= "3.7" and python_full_version < "4.0.0" and sys_platform == "win32" and python_full_version >= "3.5.0" \
|
||||||
|
--hash=sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da \
|
||||||
|
--hash=sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4
|
||||||
|
colorlog==6.6.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:351c51e866c86c3217f08e4b067a7974a678be78f07f85fc2d55b8babde6d94e \
|
||||||
|
--hash=sha256:344f73204009e4c83c5b6beb00b3c45dc70fcdae3c80db919e0a4171d006fde8
|
||||||
|
deprecated==1.2.13; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.4.0" \
|
||||||
|
--hash=sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d \
|
||||||
|
--hash=sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d
|
||||||
|
django-axes==5.35.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:bbe08d72defe8cadab4af12c6dc72c3b40e0e0a771fdeb37c20a3e20a5fc2aec \
|
||||||
|
--hash=sha256:f74c096ffff3133a49247bab9299f5280647b70bb27784475d49cbf19672458e
|
||||||
|
django-debug-toolbar==3.5.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:97965f2630692de316ea0c1ca5bfa81660d7ba13146dbc6be2059cf55b35d0e5 \
|
||||||
|
--hash=sha256:89a52128309eb4da12738801ff0c202d2ff8730d1c3225fac6acf630c303e661
|
||||||
|
django-fmd==0.0.1; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:7518fda3aa09eb8f0779dae04949dc3a22663da2c37f98cb1280c52a3ff1ce1b \
|
||||||
|
--hash=sha256:74c7205f49eb0e076ecb96284da1d9e59ff1a7e5549d4ece32ab67a4e135d5de
|
||||||
|
django-ipware==4.0.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.0" \
|
||||||
|
--hash=sha256:602a58325a4808bd19197fef2676a0b2da2df40d0ecf21be414b2ff48c72ad05 \
|
||||||
|
--hash=sha256:878dbb06a87e25550798e9ef3204ed70a200dd8b15e47dcef848cf08244f04c9
|
||||||
|
django-redis==5.2.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:8a99e5582c79f894168f5865c52bd921213253b7fd64d16733ae4591564465de \
|
||||||
|
--hash=sha256:1d037dc02b11ad7aa11f655d26dac3fb1af32630f61ef4428860a2e29ff92026
|
||||||
|
django-tools==0.50.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:c53805b60f6745d9d3a729d2b0add72eb27284362e0aef73d72b1a69704e4357 \
|
||||||
|
--hash=sha256:4ce9f524ba08d2071a762dc66e7f85ac1664b41cc8fa0ce686a651c1610b3d67
|
||||||
|
django-yunohost-integration==0.2.4; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:f5cdb5480025e90de0221d2b1c6282f517fd0c903702563cccb771cb3e1d9417 \
|
||||||
|
--hash=sha256:a4b3617a3b39225d6162fa88827e9fe8b65388e26a0bbc23ea665c62aa8cb044
|
||||||
|
django==3.2.14; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:a8681e098fa60f7c33a4b628d6fcd3fe983a0939ff1301ecacac21d0b38bad56 \
|
||||||
|
--hash=sha256:677182ba8b5b285a4e072f3ac17ceee6aff1b5ce77fd173cc5b6a2d3dc022fcf
|
||||||
|
gunicorn==20.1.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \
|
||||||
|
--hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8
|
||||||
|
icdiff==2.0.5; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:35d24b728e48b7e0a12bdb69386d3bfc7eef4fe922d0ac1cd70d6e5c11630bae
|
||||||
|
importlib-metadata==4.2.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
|
||||||
|
--hash=sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b \
|
||||||
|
--hash=sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31
|
||||||
|
packaging==21.3; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 \
|
||||||
|
--hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb
|
||||||
|
pprintpp==0.4.0; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d \
|
||||||
|
--hash=sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403
|
||||||
|
psycopg2==2.9.3; python_version >= "3.6" \
|
||||||
|
--hash=sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362 \
|
||||||
|
--hash=sha256:d3ca6421b942f60c008f81a3541e8faf6865a28d5a9b48544b0ee4f40cac7fca \
|
||||||
|
--hash=sha256:9572e08b50aed176ef6d66f15a21d823bb6f6d23152d35e8451d7d2d18fdac56 \
|
||||||
|
--hash=sha256:a81e3866f99382dfe8c15a151f1ca5fde5815fde879348fe5a9884a7c092a305 \
|
||||||
|
--hash=sha256:cb10d44e6694d763fa1078a26f7f6137d69f555a78ec85dc2ef716c37447e4b2 \
|
||||||
|
--hash=sha256:4295093a6ae3434d33ec6baab4ca5512a5082cc43c0505293087b8a46d108461 \
|
||||||
|
--hash=sha256:34b33e0162cfcaad151f249c2649fd1030010c16f4bbc40a604c1cb77173dcf7 \
|
||||||
|
--hash=sha256:0762c27d018edbcb2d34d51596e4346c983bd27c330218c56c4dc25ef7e819bf \
|
||||||
|
--hash=sha256:8cf3878353cc04b053822896bc4922b194792df9df2f1ad8da01fb3043602126 \
|
||||||
|
--hash=sha256:06f32425949bd5fe8f625c49f17ebb9784e1e4fe928b7cce72edc36fb68e4c0c \
|
||||||
|
--hash=sha256:8e841d1bf3434da985cc5ef13e6f75c8981ced601fd70cc6bf33351b91562981
|
||||||
|
pyparsing==3.0.9; python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.6.8" \
|
||||||
|
--hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc \
|
||||||
|
--hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb
|
||||||
|
python-stdnum==1.17; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:374e2b5e13912ccdbf50b0b23fca2c3e0531174805c32d74e145f37756328340 \
|
||||||
|
--hash=sha256:a46e6cf9652807314d369b654b255c86a59f93d18be2834f3d567ed1a346c547
|
||||||
|
pytz==2022.1; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c \
|
||||||
|
--hash=sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7
|
||||||
|
redis==4.3.4; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54 \
|
||||||
|
--hash=sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880
|
||||||
|
six==1.16.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.3.0" \
|
||||||
|
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 \
|
||||||
|
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926
|
||||||
|
sqlparse==0.4.2; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d \
|
||||||
|
--hash=sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae
|
||||||
|
typing-extensions==4.3.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
|
||||||
|
--hash=sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02 \
|
||||||
|
--hash=sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6
|
||||||
|
webencodings==0.5.1; python_version >= "3.7" and python_full_version < "4.0.0" \
|
||||||
|
--hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
|
||||||
|
--hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
|
||||||
|
wrapt==1.14.1; python_version >= "3.7" and python_full_version < "3.0.0" or python_version >= "3.7" and python_full_version < "4.0.0" and python_full_version >= "3.5.0" \
|
||||||
|
--hash=sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3 \
|
||||||
|
--hash=sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef \
|
||||||
|
--hash=sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28 \
|
||||||
|
--hash=sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59 \
|
||||||
|
--hash=sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87 \
|
||||||
|
--hash=sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1 \
|
||||||
|
--hash=sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b \
|
||||||
|
--hash=sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462 \
|
||||||
|
--hash=sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1 \
|
||||||
|
--hash=sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320 \
|
||||||
|
--hash=sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2 \
|
||||||
|
--hash=sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4 \
|
||||||
|
--hash=sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069 \
|
||||||
|
--hash=sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310 \
|
||||||
|
--hash=sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f \
|
||||||
|
--hash=sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656 \
|
||||||
|
--hash=sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c \
|
||||||
|
--hash=sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8 \
|
||||||
|
--hash=sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164 \
|
||||||
|
--hash=sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907 \
|
||||||
|
--hash=sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3 \
|
||||||
|
--hash=sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3 \
|
||||||
|
--hash=sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d \
|
||||||
|
--hash=sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7 \
|
||||||
|
--hash=sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00 \
|
||||||
|
--hash=sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4 \
|
||||||
|
--hash=sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1 \
|
||||||
|
--hash=sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1 \
|
||||||
|
--hash=sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff \
|
||||||
|
--hash=sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d \
|
||||||
|
--hash=sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1 \
|
||||||
|
--hash=sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569 \
|
||||||
|
--hash=sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed \
|
||||||
|
--hash=sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471 \
|
||||||
|
--hash=sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248 \
|
||||||
|
--hash=sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68 \
|
||||||
|
--hash=sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d \
|
||||||
|
--hash=sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77 \
|
||||||
|
--hash=sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7 \
|
||||||
|
--hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \
|
||||||
|
--hash=sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a \
|
||||||
|
--hash=sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853 \
|
||||||
|
--hash=sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c \
|
||||||
|
--hash=sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456 \
|
||||||
|
--hash=sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f \
|
||||||
|
--hash=sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc \
|
||||||
|
--hash=sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1 \
|
||||||
|
--hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af \
|
||||||
|
--hash=sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b \
|
||||||
|
--hash=sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0 \
|
||||||
|
--hash=sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57 \
|
||||||
|
--hash=sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5 \
|
||||||
|
--hash=sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d \
|
||||||
|
--hash=sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383 \
|
||||||
|
--hash=sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7 \
|
||||||
|
--hash=sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86 \
|
||||||
|
--hash=sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735 \
|
||||||
|
--hash=sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b \
|
||||||
|
--hash=sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3 \
|
||||||
|
--hash=sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3 \
|
||||||
|
--hash=sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe \
|
||||||
|
--hash=sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5 \
|
||||||
|
--hash=sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb \
|
||||||
|
--hash=sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d
|
||||||
|
zipp==3.8.0; python_version >= "3.7" and python_full_version < "4.0.0" and python_version < "3.8" \
|
||||||
|
--hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099 \
|
||||||
|
--hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad
|
174
conf/settings.py
Normal file
174
conf/settings.py
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
# Please do not modify this file, it will be reset at the next update.
|
||||||
|
# You can edit the file __FINAL_HOME_PATH__/local_settings.py and add/modify the settings you need.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
from pathlib import Path as __Path
|
||||||
|
|
||||||
|
from django_yunohost_integration.base_settings import * # noqa
|
||||||
|
from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret
|
||||||
|
|
||||||
|
from findmydevice_project.settings.base import * # noqa
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FINAL_HOME_PATH = __Path('__FINAL_HOME_PATH__') # /opt/yunohost/$app
|
||||||
|
assert FINAL_HOME_PATH.is_dir(), f'Directory not exists: {FINAL_HOME_PATH}'
|
||||||
|
|
||||||
|
FINAL_WWW_PATH = __Path('__FINAL_WWW_PATH__') # /var/www/$app
|
||||||
|
assert FINAL_WWW_PATH.is_dir(), f'Directory not exists: {FINAL_WWW_PATH}'
|
||||||
|
|
||||||
|
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django-fmd.log
|
||||||
|
assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}'
|
||||||
|
|
||||||
|
PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH
|
||||||
|
PATH_URL = PATH_URL.strip('/')
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'urls' # /opt/yunohost/django-fmd/ynh_urls.py
|
||||||
|
|
||||||
|
# Function that will be called to finalize a user profile:
|
||||||
|
YNH_SETUP_USER = 'setup_user.setup_project_user'
|
||||||
|
|
||||||
|
SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt
|
||||||
|
|
||||||
|
INSTALLED_APPS.append('django_yunohost_integration')
|
||||||
|
|
||||||
|
MIDDLEWARE.insert(
|
||||||
|
MIDDLEWARE.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
|
||||||
|
# login a user via HTTP_REMOTE_USER header from SSOwat:
|
||||||
|
'django_yunohost_integration.sso_auth.auth_middleware.SSOwatRemoteUserMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
# Keep ModelBackend around for per-user permissions and superuser
|
||||||
|
AUTHENTICATION_BACKENDS = (
|
||||||
|
# Authenticate via SSO and nginx 'HTTP_REMOTE_USER' header:
|
||||||
|
'django_yunohost_integration.sso_auth.auth_backend.SSOwatUserBackend',
|
||||||
|
#
|
||||||
|
# Fallback to normal Django model backend:
|
||||||
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
|
)
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = None
|
||||||
|
LOGIN_URL = '/yunohost/sso/'
|
||||||
|
LOGOUT_REDIRECT_URL = '/yunohost/sso/'
|
||||||
|
# /yunohost/sso/?action=logout
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ADMINS = (('__ADMIN__', '__ADMINMAIL__'),)
|
||||||
|
|
||||||
|
MANAGERS = ADMINS
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
|
'NAME': '__DB_NAME__',
|
||||||
|
'USER': '__DB_USER__',
|
||||||
|
'PASSWORD': '__DB_PWD__',
|
||||||
|
'HOST': '127.0.0.1',
|
||||||
|
'PORT': '5432', # Default Postgres Port
|
||||||
|
'CONN_MAX_AGE': 600,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Title of site to use
|
||||||
|
SITE_TITLE = '__APP__'
|
||||||
|
|
||||||
|
# Site domain
|
||||||
|
SITE_DOMAIN = '__DOMAIN__'
|
||||||
|
|
||||||
|
# Subject of emails includes site title
|
||||||
|
EMAIL_SUBJECT_PREFIX = f'[{SITE_TITLE}] '
|
||||||
|
|
||||||
|
|
||||||
|
# E-mail address that error messages come from.
|
||||||
|
SERVER_EMAIL = 'noreply@__DOMAIN__'
|
||||||
|
|
||||||
|
# Default email address to use for various automated correspondence from
|
||||||
|
# the site managers. Used for registration emails.
|
||||||
|
DEFAULT_FROM_EMAIL = '__ADMINMAIL__'
|
||||||
|
|
||||||
|
# List of URLs your site is supposed to serve
|
||||||
|
ALLOWED_HOSTS = ['__DOMAIN__']
|
||||||
|
|
||||||
|
# _____________________________________________________________________________
|
||||||
|
# Configuration for caching
|
||||||
|
CACHES = {
|
||||||
|
'default': {
|
||||||
|
'BACKEND': 'django_redis.cache.RedisCache',
|
||||||
|
'LOCATION': 'redis://127.0.0.1:6379/__REDIS_DB__',
|
||||||
|
# If redis is running on same host as django-fmd, you might
|
||||||
|
# want to use unix sockets instead:
|
||||||
|
# 'LOCATION': 'unix:///var/run/redis/redis.sock?db=1',
|
||||||
|
'OPTIONS': {
|
||||||
|
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
|
||||||
|
},
|
||||||
|
'KEY_PREFIX': '__APP__',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# _____________________________________________________________________________
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
|
||||||
|
if PATH_URL:
|
||||||
|
STATIC_URL = f'/{PATH_URL}/static/'
|
||||||
|
MEDIA_URL = f'/{PATH_URL}/media/'
|
||||||
|
else:
|
||||||
|
# Installed to domain root, without a path prefix?
|
||||||
|
STATIC_URL = '/static/'
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
|
||||||
|
STATIC_ROOT = str(FINAL_WWW_PATH / 'static')
|
||||||
|
MEDIA_ROOT = str(FINAL_WWW_PATH / 'media')
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': True,
|
||||||
|
'formatters': {
|
||||||
|
'verbose': {
|
||||||
|
'format': '{asctime} {levelname} {name} {module}.{funcName} {message}',
|
||||||
|
'style': '{',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'mail_admins': {
|
||||||
|
'level': 'ERROR',
|
||||||
|
'formatter': 'verbose',
|
||||||
|
'class': 'django.utils.log.AdminEmailHandler',
|
||||||
|
'include_html': True,
|
||||||
|
},
|
||||||
|
'log_file': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'class': 'logging.handlers.WatchedFileHandler',
|
||||||
|
'formatter': 'verbose',
|
||||||
|
'filename': str(LOG_FILE),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
|
||||||
|
'django': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
|
||||||
|
'axes': {'handlers': ['log_file', 'mail_admins'], 'level': 'WARNING', 'propagate': False},
|
||||||
|
'django_tools': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
|
||||||
|
'django_yunohost_integration': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
|
||||||
|
'findmydevice': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
try:
|
||||||
|
from local_settings import * # noqa
|
||||||
|
except ImportError:
|
||||||
|
pass
|
8
conf/setup_user.py
Normal file
8
conf/setup_user.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
def setup_project_user(user):
|
||||||
|
"""
|
||||||
|
All users used the Django admin, so we need to set the "staff" user flag.
|
||||||
|
Called from django_yunohost_integration.sso_auth
|
||||||
|
"""
|
||||||
|
user.is_staff = True
|
||||||
|
user.save()
|
||||||
|
return user
|
22
conf/urls.py
Normal file
22
conf/urls.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls import static
|
||||||
|
from django.urls import include, path
|
||||||
|
|
||||||
|
|
||||||
|
# from django_yunohost_integration.views import request_media_debug_view
|
||||||
|
|
||||||
|
|
||||||
|
if settings.PATH_URL:
|
||||||
|
# settings.PATH_URL is the $YNH_APP_ARG_PATH
|
||||||
|
# Prefix all urls with "PATH_URL":
|
||||||
|
urlpatterns = [
|
||||||
|
# path(f'{settings.PATH_URL}/debug/', request_media_debug_view),
|
||||||
|
|
||||||
|
path(f'{settings.PATH_URL}/', include('findmydevice_project.urls')),
|
||||||
|
]
|
||||||
|
if settings.SERVE_FILES:
|
||||||
|
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
else:
|
||||||
|
# Installed to domain root, without a path prefix
|
||||||
|
# Just use the default project urls.py
|
||||||
|
from findmydevice_project.urls import urlpatterns # noqa
|
12
conf/wsgi.py
Normal file
12
conf/wsgi.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
"""
|
||||||
|
WSGI config
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application # noqa
|
||||||
|
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
20
config_panel.toml
Normal file
20
config_panel.toml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# https://github.com/YunoHost/example_ynh/blob/master/config_panel.toml.example
|
||||||
|
|
||||||
|
version = "1.0"
|
||||||
|
|
||||||
|
[main]
|
||||||
|
name = "Settings"
|
||||||
|
|
||||||
|
[main.findmydevice_config]
|
||||||
|
name = "django-fmd configuration"
|
||||||
|
|
||||||
|
# Trigger a service reload-or-restart after the user change a question in this panel
|
||||||
|
services = ["__APP__"]
|
||||||
|
|
||||||
|
[main.findmydevice_config.django_debug]
|
||||||
|
ask = "debug mode"
|
||||||
|
help = "Important: Never activate this settings.DEBUG on production!"
|
||||||
|
type = "boolean"
|
||||||
|
yes = "True"
|
||||||
|
no = "False"
|
||||||
|
bind = "DJANGO_DEBUG:__FINALPATH__/local_settings.py"
|
14
doc/DESCRIPTION.md
Normal file
14
doc/DESCRIPTION.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Find My Device Server implemented in Python using Django.
|
||||||
|
Usable for the Andorid App [**FindMyDevice**](https://gitlab.com/Nulide/findmydevice/) by [Nnulide](https://nulide.de/):
|
||||||
|
|
||||||
|
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get FindMyDevice on F-Droid" height="80">](https://f-droid.org/packages/de.nulide.findmydevice/)
|
||||||
|
|
||||||
|
[![pytest](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml/badge.svg?branch=master)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/pytest.yml) [![YunoHost apps package linter](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml/badge.svg)](https://github.com/YunoHost-Apps/django-fmd_ynh/actions/workflows/package_linter.yml) [![Coverage Status on codecov.io](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh/branch/master/graph/badge.svg)](https://codecov.io/gh/YunoHost-Apps/django-fmd_ynh)
|
||||||
|
|
||||||
|
![django-fmd @ PyPi](https://img.shields.io/pypi/v/django-fmd?label=django-fmd%20%40%20PyPi)
|
||||||
|
![Python Versions](https://img.shields.io/pypi/pyversions/django-fmd)
|
||||||
|
![License GPL V3+](https://img.shields.io/pypi/l/django-fmd)
|
||||||
|
|
||||||
|
Pull requests welcome ;)
|
||||||
|
|
||||||
|
This package for YunoHost used [django-yunohost-integration](https://github.com/YunoHost-Apps/django_yunohost_integration)
|
128
doc/DISCLAIMER.md
Normal file
128
doc/DISCLAIMER.md
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
## Settings and upgrades
|
||||||
|
|
||||||
|
Almost everything related to django-fmd's configuration is handled in a `"../conf/settings.py"` file.
|
||||||
|
You can edit the file `/opt/yunohost/django-fmd/local_settings.py` to enable or disable features.
|
||||||
|
|
||||||
|
Test sending emails:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh admin@yourdomain.tld
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
Background info: Error mails are send to all [settings.ADMINS](https://docs.djangoproject.com/en/2.2/ref/settings/#std:setting-ADMINS). By default the YunoHost admin is inserted here.
|
||||||
|
To check current ADMINS run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py sendtestemail --admins
|
||||||
|
```
|
||||||
|
|
||||||
|
If you prefere to send error emails to a extrnal email address, just do something like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "ADMINS = (('Your Name', 'example@domain.tld'),)" >> /opt/yunohost/django-fmd/local_settings.py
|
||||||
|
```
|
||||||
|
|
||||||
|
To check the effective settings, run this:
|
||||||
|
```bash
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./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
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Yunohost developer commands
|
||||||
|
|
||||||
|
To remove call e.g.:
|
||||||
|
```bash
|
||||||
|
sudo yunohost app remove django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Backup / remove / restore cycle, e.g.:
|
||||||
|
```bash
|
||||||
|
yunohost backup create --apps django-fmd
|
||||||
|
yunohost backup list
|
||||||
|
archives:
|
||||||
|
- django-fmd-pre-upgrade1
|
||||||
|
- 20201223-163434
|
||||||
|
yunohost app remove django-fmd
|
||||||
|
yunohost backup restore 20201223-163434 --apps django-fmd
|
||||||
|
```
|
||||||
|
|
||||||
|
Debug installation, e.g.:
|
||||||
|
```bash
|
||||||
|
root@yunohost:~# ls -la /var/www/django-fmd/
|
||||||
|
total 18
|
||||||
|
drwxr-xr-x 4 root root 4 Dec 8 08:36 .
|
||||||
|
drwxr-xr-x 6 root root 6 Dec 8 08:36 ..
|
||||||
|
drwxr-xr-x 2 root root 2 Dec 8 08:36 media
|
||||||
|
drwxr-xr-x 7 root root 8 Dec 8 08:40 static
|
||||||
|
|
||||||
|
root@yunohost:~# ls -la /opt/yunohost/django-fmd/
|
||||||
|
total 58
|
||||||
|
drwxr-xr-x 5 django-fmd django-fmd 11 Dec 8 08:39 .
|
||||||
|
drwxr-xr-x 3 root root 3 Dec 8 08:36 ..
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 460 Dec 8 08:39 gunicorn.conf.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 0 Dec 8 08:39 local_settings.py
|
||||||
|
-rwxr-xr-x 1 django-fmd django-fmd 274 Dec 8 08:39 manage.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 171 Dec 8 08:39 secret.txt
|
||||||
|
drwxr-xr-x 6 django-fmd django-fmd 6 Dec 8 08:37 venv
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 115 Dec 8 08:39 wsgi.py
|
||||||
|
-rw-r--r-- 1 django-fmd django-fmd 4737 Dec 8 08:39 settings.py
|
||||||
|
|
||||||
|
root@yunohost:~# cd /opt/yunohost/django-fmd/
|
||||||
|
root@yunohost:/opt/yunohost/django-fmd# source venv/bin/activate
|
||||||
|
(venv) root@yunohost:/opt/yunohost/django-fmd# ./manage.py check
|
||||||
|
django-fmd v0.8.2 (Django v2.2.17)
|
||||||
|
DJANGO_SETTINGS_MODULE='settings'
|
||||||
|
PROJECT_PATH:/opt/yunohost/django-fmd/venv/lib/python3.7/site-packages
|
||||||
|
BASE_PATH:/opt/yunohost/django-fmd
|
||||||
|
System check identified no issues (0 silenced).
|
||||||
|
|
||||||
|
root@yunohost:~# tail -f /var/log/django-fmd/django-fmd.log
|
||||||
|
root@yunohost:~# cat /etc/systemd/system/django-fmd.service
|
||||||
|
|
||||||
|
root@yunohost:~# systemctl reload-or-restart django-fmd
|
||||||
|
root@yunohost:~# journalctl --unit=django-fmd --follow
|
||||||
|
```
|
||||||
|
|
||||||
|
## local test
|
||||||
|
|
||||||
|
For quicker developing of django-fmd in the context of YunoHost app,
|
||||||
|
it's possible to run the Django developer server with the settings
|
||||||
|
and urls made for YunoHost installation.
|
||||||
|
|
||||||
|
e.g.:
|
||||||
|
```bash
|
||||||
|
~$ git clone https://github.com/YunoHost-Apps/django-fmd_ynh.git
|
||||||
|
~$ cd django-fmd_ynh/
|
||||||
|
~/django-fmd_ynh$ make
|
||||||
|
install-poetry install or update poetry
|
||||||
|
install install django-fmd via poetry
|
||||||
|
update update the sources and installation
|
||||||
|
local-test Run local_test.py to run django-fmd_ynh locally
|
||||||
|
~/django-fmd_ynh$ make install-poetry
|
||||||
|
~/django-fmd_ynh$ make install
|
||||||
|
~/django-fmd_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/`
|
29
local_test.py
Normal file
29
local_test.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
"""
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
46
manifest.json
Normal file
46
manifest.json
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
{
|
||||||
|
"name": "django-fmd",
|
||||||
|
"id": "django-fmd",
|
||||||
|
"packaging_format": 1,
|
||||||
|
"description": {
|
||||||
|
"en": "Web based FritzBox management using Python/Django."
|
||||||
|
},
|
||||||
|
"version": "0.0.1~ynh1",
|
||||||
|
"url": "https://gitlab.com/jedie/django-find-my-device",
|
||||||
|
"upstream": {
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"website": "https://gitlab.com/jedie/django-find-my-device",
|
||||||
|
"code": "https://gitlab.com/jedie/django-find-my-device"
|
||||||
|
},
|
||||||
|
"license": "GPL-3.0",
|
||||||
|
"maintainer": {
|
||||||
|
"name": "Jens Diemer",
|
||||||
|
"email": "django-fmd_ynh@jensdiemer.de"
|
||||||
|
},
|
||||||
|
"previous_maintainers": [],
|
||||||
|
"requirements": {
|
||||||
|
"yunohost": ">= 4.3.0"
|
||||||
|
},
|
||||||
|
"multi_instance": true,
|
||||||
|
"services": [
|
||||||
|
"nginx"
|
||||||
|
],
|
||||||
|
"arguments": {
|
||||||
|
"install" : [
|
||||||
|
{
|
||||||
|
"name": "domain",
|
||||||
|
"type": "domain"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "path",
|
||||||
|
"type": "path",
|
||||||
|
"example": "/django-fmd",
|
||||||
|
"default": "/django-fmd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "admin",
|
||||||
|
"type": "user"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
1327
poetry.lock
generated
Normal file
1327
poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
112
pyproject.toml
Normal file
112
pyproject.toml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
[tool.poetry]
|
||||||
|
name = "django-fmd_ynh"
|
||||||
|
version = "0.0.1~ynh1"
|
||||||
|
description = "Test django-fmd_ynh via local_test.py"
|
||||||
|
authors = ["JensDiemer <git@jensdiemer.de>"]
|
||||||
|
license = "GPL"
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
# Keep Python 3.7 until Yunohost contains a newer Python Version ;)
|
||||||
|
python = ">=3.7,<4.0.0"
|
||||||
|
django-fmd = ">=0.0.1" # https://gitlab.com/jedie/django-find-my-device
|
||||||
|
|
||||||
|
# Note: "ynh" extras will install gunicorn, psycopg2, django-redis and django-axes
|
||||||
|
django_yunohost_integration = {version = ">=v0.2.0", extras = ["ynh"]}
|
||||||
|
|
||||||
|
psycopg2 = "*" # https://www.psycopg.org/docs/install.html#build-prerequisites
|
||||||
|
|
||||||
|
[tool.poetry.dev-dependencies]
|
||||||
|
bx_py_utils = "*"
|
||||||
|
tox = "*"
|
||||||
|
pytest = "*"
|
||||||
|
pytest-cov = "*"
|
||||||
|
pytest-django = "*"
|
||||||
|
pytest-darker = "*" # https://github.com/akaihola/pytest-darker
|
||||||
|
pytest-flake8 = "*"
|
||||||
|
pytest-isort = "*"
|
||||||
|
coveralls = "*"
|
||||||
|
isort = "*"
|
||||||
|
flake8 = "*"
|
||||||
|
flynt = "*"
|
||||||
|
darker = "*" # https://github.com/akaihola/darker
|
||||||
|
pyupgrade = "*"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core>=1.0.0"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
|
[tool.darker]
|
||||||
|
src = ['.']
|
||||||
|
revision = "origin/master..."
|
||||||
|
line_length = 100
|
||||||
|
verbose = true
|
||||||
|
skip_string_normalization = true
|
||||||
|
diff = false
|
||||||
|
check = false
|
||||||
|
stdout = false
|
||||||
|
isort = true
|
||||||
|
lint = [
|
||||||
|
"flake8",
|
||||||
|
]
|
||||||
|
log_level = "INFO"
|
||||||
|
|
||||||
|
|
||||||
|
[tool.flynt]
|
||||||
|
line_length = 100
|
||||||
|
|
||||||
|
|
||||||
|
[tool.isort]
|
||||||
|
# https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format
|
||||||
|
atomic=true
|
||||||
|
profile='black'
|
||||||
|
line_length=100
|
||||||
|
skip_glob=["*/htmlcov/*","*/migrations/*"]
|
||||||
|
known_first_party=["findmydevice","findmydevice_project","findmydevice_tests"]
|
||||||
|
lines_after_imports=2
|
||||||
|
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
# https://docs.pytest.org/en/latest/customize.html#pyproject-toml
|
||||||
|
minversion = "6.0"
|
||||||
|
norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov"
|
||||||
|
# sometimes helpfull "addopts" arguments:
|
||||||
|
# -vv
|
||||||
|
# --verbose
|
||||||
|
# --capture=no
|
||||||
|
# --trace-config
|
||||||
|
# --full-trace
|
||||||
|
# -p no:warnings
|
||||||
|
addopts = """
|
||||||
|
--reuse-db
|
||||||
|
--nomigrations
|
||||||
|
--cov=.
|
||||||
|
--cov-report term-missing
|
||||||
|
--cov-report html
|
||||||
|
--cov-report xml
|
||||||
|
--no-cov-on-fail
|
||||||
|
--showlocals
|
||||||
|
--darker
|
||||||
|
--flake8
|
||||||
|
--isort
|
||||||
|
--doctest-modules
|
||||||
|
--failed-first
|
||||||
|
--last-failed-no-failures all
|
||||||
|
--new-first
|
||||||
|
"""
|
||||||
|
# TODO: --mypy
|
||||||
|
|
||||||
|
[tool.tox]
|
||||||
|
# https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini
|
||||||
|
legacy_tox_ini = """
|
||||||
|
[tox]
|
||||||
|
isolated_build = True
|
||||||
|
envlist = px310,py39,py38,py37
|
||||||
|
skip_missing_interpreters = True
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
passenv = *
|
||||||
|
whitelist_externals = make
|
||||||
|
commands =
|
||||||
|
pytest findmydevice findmydevice_project
|
||||||
|
"""
|
25
run_pytest.py
Normal file
25
run_pytest.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
"""
|
||||||
|
Run pytest against local test creation
|
||||||
|
"""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from django_yunohost_integration.pytest_helper import run_pytest
|
||||||
|
except ImportError as err:
|
||||||
|
raise ImportError('Did you forget to activate a virtual environment?') from err
|
||||||
|
|
||||||
|
|
||||||
|
BASE_PATH = Path(__file__).parent
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
run_pytest(
|
||||||
|
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
|
||||||
|
destination=BASE_PATH / 'local_test',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
90
scripts/_common.sh
Normal file
90
scripts/_common.sh
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RETRIEVE ARGUMENTS FROM THE MANIFEST
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
domain=$YNH_APP_ARG_DOMAIN
|
||||||
|
path_url=$YNH_APP_ARG_PATH
|
||||||
|
|
||||||
|
admin=$YNH_APP_ARG_ADMIN
|
||||||
|
app=$YNH_APP_INSTANCE_NAME
|
||||||
|
|
||||||
|
# Currently not used: django-fmd has no public pages, yet!
|
||||||
|
is_public=$YNH_APP_ARG_IS_PUBLIC
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SET CONSTANTS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
public_path=/var/www/$app
|
||||||
|
final_path=/opt/yunohost/$app
|
||||||
|
log_path=/var/log/$app
|
||||||
|
log_file="${log_path}/django-fmd.log"
|
||||||
|
|
||||||
|
# Default: settings.DEBUG=False
|
||||||
|
django_debug="False"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# COMMON VARIABLES
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# dependencies used by the app
|
||||||
|
pkg_dependencies="build-essential python3-dev python3-pip python3-venv git libpq-dev postgresql postgresql-contrib libjpeg-dev"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# Redis HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# get the first available redis database
|
||||||
|
#
|
||||||
|
# usage: ynh_redis_get_free_db
|
||||||
|
# | returns: the database number to use
|
||||||
|
ynh_redis_get_free_db() {
|
||||||
|
local result max db
|
||||||
|
result=$(redis-cli INFO keyspace)
|
||||||
|
|
||||||
|
# get the num
|
||||||
|
max=$(cat /etc/redis/redis.conf | grep ^databases | grep -Eow "[0-9]+")
|
||||||
|
|
||||||
|
db=0
|
||||||
|
# default Debian setting is 15 databases
|
||||||
|
for i in $(seq 0 "$max")
|
||||||
|
do
|
||||||
|
if ! echo "$result" | grep -q "db$i"
|
||||||
|
then
|
||||||
|
db=$i
|
||||||
|
break 1
|
||||||
|
fi
|
||||||
|
db=-1
|
||||||
|
done
|
||||||
|
|
||||||
|
test "$db" -eq -1 && ynh_die "No available Redis databases..."
|
||||||
|
|
||||||
|
echo "$db"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a master password and set up global settings
|
||||||
|
# Please always call this script in install and restore scripts
|
||||||
|
#
|
||||||
|
# usage: ynh_redis_remove_db database
|
||||||
|
# | arg: database - the database to erase
|
||||||
|
ynh_redis_remove_db() {
|
||||||
|
local db=$1
|
||||||
|
redis-cli -n "$db" flushall
|
||||||
|
}
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Execute a command as another user
|
||||||
|
# usage: ynh_exec_as USER COMMAND [ARG ...]
|
||||||
|
ynh_exec_as() {
|
||||||
|
local USER=$1
|
||||||
|
shift 1
|
||||||
|
|
||||||
|
if [[ $USER = $(whoami) ]]; then
|
||||||
|
eval "$@"
|
||||||
|
else
|
||||||
|
sudo -u "$USER" "$@"
|
||||||
|
fi
|
||||||
|
}
|
69
scripts/backup
Executable file
69
scripts/backup
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC START
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source ../settings/scripts/_common.sh
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
ynh_print_info --message="Declaring files to be backed up..."
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# BACKUP THE APP MAIN DIR
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_backup --src_path="$final_path"
|
||||||
|
ynh_backup --src_path="$public_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# BACKUP THE NGINX CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_backup --src_path="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# BACKUP THE PostgreSQL DATABASE
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_psql_dump_db --database="$db_name" > db.sql
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SPECIFIC BACKUP
|
||||||
|
#=================================================
|
||||||
|
# BACKUP LOGROTATE
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_backup --src_path="/etc/logrotate.d/$app"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# BACKUP SYSTEMD
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_backup --src_path="/etc/systemd/system/$app.service"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# END OF SCRIPT
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_print_info --message="Backup script completed for $app. (YunoHost will then actually copy those files to the archive)."
|
159
scripts/change_url
Normal file
159
scripts/change_url
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC STARTING
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source _common.sh
|
||||||
|
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)
|
||||||
|
admin_mail=$(ynh_user_get_info "$admin" mail)
|
||||||
|
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# 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
|
||||||
|
#=================================================
|
||||||
|
# STOP SYSTEMD SERVICE
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Stopping systemd services..."
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="stop"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# STANDARD MODIFICATIONS
|
||||||
|
#=================================================
|
||||||
|
# MODIFY URL IN NGINX CONF
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Updating nginx web server configuration..."
|
||||||
|
|
||||||
|
nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf
|
||||||
|
|
||||||
|
# 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
|
||||||
|
#=================================================
|
||||||
|
# MODIFY SETTINGS
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Modify django-fmd's config file..."
|
||||||
|
|
||||||
|
# save old settings file
|
||||||
|
settings="$final_path/settings.py"
|
||||||
|
ynh_backup_if_checksum_is_different --file="$settings"
|
||||||
|
|
||||||
|
cp "../conf/settings.py" "$settings"
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
|
||||||
|
|
||||||
|
# Difference to install/upgrade scripts: Use $new_domain and $new_path here:
|
||||||
|
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$new_domain" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$new_path" --target_file="$settings"
|
||||||
|
|
||||||
|
# Recalculate and store the config file checksum into the app settings
|
||||||
|
ynh_store_file_checksum --file="$settings"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC FINALISATION
|
||||||
|
#=================================================
|
||||||
|
# START SYSTEMD SERVICE
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Starting systemd services..." --weight=5
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="start"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RELOAD NGINX
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Reloading nginx web server..."
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# END OF SCRIPT
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_script_progression --message="Change of URL completed for $app" --last
|
249
scripts/install
Executable file
249
scripts/install
Executable file
|
@ -0,0 +1,249 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source _common.sh
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# MANAGE SCRIPT FAILURE
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Exit if an error occurs during the execution of the script
|
||||||
|
ynh_abort_if_errors
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Validating installation parameters..."
|
||||||
|
|
||||||
|
# Path for e.g. "static" files, served by nginx:
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Storing installation settings..."
|
||||||
|
|
||||||
|
ynh_app_setting_set --app="$app" --key=admin --value="$admin"
|
||||||
|
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"
|
||||||
|
ynh_app_setting_set --app="$app" --key=path --value="$path_url"
|
||||||
|
|
||||||
|
# Find a free port
|
||||||
|
port=$(ynh_find_port --port=8000)
|
||||||
|
# Set port as application setting
|
||||||
|
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/setting
|
||||||
|
ynh_app_setting_set --app="$app" --key=port --value="$port"
|
||||||
|
|
||||||
|
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
|
||||||
|
admin_mail=$(ynh_user_get_info --username="$admin" --key=mail)
|
||||||
|
redis_db=$(ynh_redis_get_free_db)
|
||||||
|
|
||||||
|
# Always deactivate settings.DEBUG:
|
||||||
|
ynh_app_setting_set --app=$app --key=django_debug --value="False"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# STANDARD MODIFICATIONS
|
||||||
|
#=================================================
|
||||||
|
# INSTALL DEPENDENCIES
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Installing dependencies..." --weight=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://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx
|
||||||
|
ynh_add_nginx_config "public_path" "port"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# CREATE DEDICATED USER
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Configuring system user..."
|
||||||
|
|
||||||
|
# A home directory for venv and settings etc.
|
||||||
|
ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# PIP INSTALLATION
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Install project via pip..." --weight=50
|
||||||
|
|
||||||
|
# Always recreate everything fresh with current python version
|
||||||
|
ynh_secure_remove "${final_path}/venv"
|
||||||
|
|
||||||
|
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||||
|
python3 -m venv --without-pip "${final_path}/venv"
|
||||||
|
|
||||||
|
cp ../conf/requirements.txt "$final_path/requirements.txt"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
#run source in a 'sub shell'
|
||||||
|
(
|
||||||
|
set +o nounset
|
||||||
|
source "${final_path}/venv/bin/activate"
|
||||||
|
set -o nounset
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# copy config files
|
||||||
|
# ================================================
|
||||||
|
ynh_script_progression --message="Create project configuration files..."
|
||||||
|
|
||||||
|
gunicorn_conf="$final_path/gunicorn.conf.py"
|
||||||
|
cp "../conf/gunicorn.conf.py" "$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf"
|
||||||
|
ynh_store_file_checksum --file="$gunicorn_conf"
|
||||||
|
|
||||||
|
cp ../conf/manage.py "$final_path/manage.py"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
|
||||||
|
ynh_store_file_checksum --file="$final_path/manage.py"
|
||||||
|
chmod +x "$final_path/manage.py"
|
||||||
|
|
||||||
|
settings="$final_path/settings.py"
|
||||||
|
cp "../conf/settings.py" "$settings"
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings"
|
||||||
|
|
||||||
|
# Calculate and store the config file checksum into the app settings
|
||||||
|
ynh_store_file_checksum --file="$settings"
|
||||||
|
|
||||||
|
ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db"
|
||||||
|
|
||||||
|
cp ../conf/setup_user.py "$final_path/setup_user.py"
|
||||||
|
cp ../conf/urls.py "$final_path/urls.py"
|
||||||
|
cp ../conf/wsgi.py "$final_path/wsgi.py"
|
||||||
|
|
||||||
|
ynh_add_config --template="local_settings.py" --destination="$final_path/local_settings.py"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# MIGRATE / COLLECTSTATIC / CREATEADMIN
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
||||||
|
|
||||||
|
cd "$final_path" || exit
|
||||||
|
|
||||||
|
# Just for debugging:
|
||||||
|
./manage.py diffsettings
|
||||||
|
|
||||||
|
./manage.py migrate --no-input
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
|
||||||
|
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
|
||||||
|
./manage.py create_superuser --username="$admin" --email="$admin_mail"
|
||||||
|
|
||||||
|
# Check the configuration
|
||||||
|
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
|
||||||
|
./manage.py check --deploy || true
|
||||||
|
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SETUP LOGROTATE
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Configuring log rotation..."
|
||||||
|
|
||||||
|
# Use logrotate to manage app-specific logfile(s)
|
||||||
|
ynh_use_logrotate "$log_file"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# INTEGRATE SERVICE IN YUNOHOST
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
|
yunohost service add $app --description="Web based management to catalog things" --log="${log_file}"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC FINALIZATION
|
||||||
|
#=================================================
|
||||||
|
# SECURE FILES AND DIRECTORIES
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Set permissions to app files
|
||||||
|
chown -R "$app:" "$log_path"
|
||||||
|
chown -R "$app:www-data" "$public_path"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
chmod o-rwx "$log_path"
|
||||||
|
chmod o-rwx "$public_path"
|
||||||
|
chmod o-rwx "$final_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SETUP SYSTEMD
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Configuring a systemd service..."
|
||||||
|
|
||||||
|
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd
|
||||||
|
ynh_add_systemd_config --service="$app" --template="django-fmd.service"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# Start django-fmd via systemd
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Starting django-fmd's services..." --weight=5
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="start"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RELOAD NGINX
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Reloading nginx web server..."
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="nginx" --action="reload"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# END OF SCRIPT
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_script_progression --message="Installation of $app completed" --last
|
103
scripts/remove
Executable file
103
scripts/remove
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC START
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source _common.sh
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
# REMOVE SERVICE FROM ADMIN PANEL
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Remove a service from the admin panel, added by `yunohost service add`
|
||||||
|
if yunohost service status "$app" >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
ynh_script_progression --message="Removing $app service integration..."
|
||||||
|
yunohost service remove "$app"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# STOP PYINVENTORY'S SERVICES
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Stopping and removing systemd services..." --weight=5
|
||||||
|
|
||||||
|
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
|
||||||
|
##=================================================
|
||||||
|
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Removing app main directory..."
|
||||||
|
|
||||||
|
# Remove the app directory securely
|
||||||
|
ynh_secure_remove --file="$public_path"
|
||||||
|
ynh_secure_remove --file="$final_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# REMOVE NGINX CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Removing nginx web server configuration..."
|
||||||
|
|
||||||
|
# Remove the dedicated nginx config
|
||||||
|
ynh_remove_nginx_config
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# REMOVE LOGROTATE CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Removing logrotate configuration..."
|
||||||
|
|
||||||
|
# Remove the app-specific logrotate config
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Removal of $app completed" --last
|
173
scripts/restore
Executable file
173
scripts/restore
Executable file
|
@ -0,0 +1,173 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC START
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source ../settings/scripts/_common.sh
|
||||||
|
source /usr/share/yunohost/helpers
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# MANAGE SCRIPT FAILURE
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_abort_if_errors
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# LOAD SETTINGS
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Loading settings..."
|
||||||
|
|
||||||
|
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
|
||||||
|
final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
|
||||||
|
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..."
|
||||||
|
|
||||||
|
ynh_webpath_available --domain=$domain --path_url=$path_url \
|
||||||
|
|| ynh_die --message="Path not available: ${domain}${path_url}"
|
||||||
|
test ! -d $final_path \
|
||||||
|
|| ynh_die --message="There is already a directory: $final_path "
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# STANDARD RESTORATION STEPS
|
||||||
|
#=================================================
|
||||||
|
# RESTORE THE NGINX CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RESTORE THE APP MAIN DIR
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Restoring the app main directory..."
|
||||||
|
|
||||||
|
ynh_restore_file --origin_path="$public_path"
|
||||||
|
ynh_restore_file --origin_path="$final_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RECREATE THE DEDICATED USER
|
||||||
|
#=================================================
|
||||||
|
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"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# REINSTALL PYTHON VIRTUALENV
|
||||||
|
# Maybe the backup contains a other Python version
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Upgrade Python virtualenv..." --weight=50
|
||||||
|
|
||||||
|
# Always recreate everything fresh with current python version
|
||||||
|
ynh_secure_remove "${final_path}/venv"
|
||||||
|
|
||||||
|
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||||
|
python3 -m venv --without-pip "${final_path}/venv"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
#run source in a 'sub shell'
|
||||||
|
(
|
||||||
|
set +o nounset
|
||||||
|
source "${final_path}/venv/bin/activate"
|
||||||
|
set -o nounset
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RESTORE THE PostgreSQL DATABASE
|
||||||
|
#=================================================
|
||||||
|
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
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RESTORE SYSTEMD
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Restoring the systemd configuration..."
|
||||||
|
|
||||||
|
ynh_restore_file --origin_path="/etc/systemd/system/$app.service"
|
||||||
|
systemctl enable $app.service --quiet
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# INTEGRATE SERVICE IN YUNOHOST
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
|
yunohost service add $app --description="Web based management to catalog things" --log="${log_file}"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RESTORE THE LOGROTATE CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
mkdir -p "$log_path"
|
||||||
|
touch "${log_file}"
|
||||||
|
chown -R "$app:" "$log_path"
|
||||||
|
ynh_restore_file --origin_path="/etc/logrotate.d/$app"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC FINALIZATION
|
||||||
|
#=================================================
|
||||||
|
# SECURE FILES AND DIRECTORIES
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Set permissions to app files
|
||||||
|
chown -R "$app:" "$log_path"
|
||||||
|
chown -R "$app:www-data" "$public_path"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
chmod o-rwx "$log_path"
|
||||||
|
chmod o-rwx "$public_path"
|
||||||
|
chmod o-rwx "$final_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC FINALIZATION
|
||||||
|
#=================================================
|
||||||
|
# START PYINVENTORY
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Starting a systemd service..." --weight=5
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="start"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RELOAD NGINX
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Reloading nginx web server..."
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="nginx" --action="reload"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# END OF SCRIPT
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Restoration completed for $app" --last
|
244
scripts/upgrade
Executable file
244
scripts/upgrade
Executable file
|
@ -0,0 +1,244 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# IMPORT GENERIC HELPERS
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
source _common.sh
|
||||||
|
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
|
||||||
|
|
||||||
|
admin_mail=$(ynh_user_get_info "$admin" mail)
|
||||||
|
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
|
||||||
|
|
||||||
|
django_debug=$(ynh_app_setting_get --app="$app" --key=django_debug)
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Backing up the 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
|
||||||
|
#=================================================
|
||||||
|
# STOP SYSTEMD SERVICE
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Stopping systemd services..." --weight=5
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="stop"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# Manage old settings
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Always deactivate settings.DEBUG:
|
||||||
|
ynh_app_setting_set --app=$app --key=django_debug --value="False"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# NGINX CONFIGURATION
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Upgrading nginx web server configuration..."
|
||||||
|
|
||||||
|
# Create a dedicated nginx config
|
||||||
|
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx
|
||||||
|
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
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Configuring a systemd service..."
|
||||||
|
|
||||||
|
ynh_add_systemd_config --service="$app" --template="django-fmd.service"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# UPGRADE VENV
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Upgrade project via pip..." --weight=50
|
||||||
|
|
||||||
|
# Always recreate everything fresh with current python version
|
||||||
|
ynh_secure_remove "${final_path}/venv"
|
||||||
|
|
||||||
|
# Skip pip because of: https://github.com/YunoHost/issues/issues/1960
|
||||||
|
python3 -m venv --without-pip "${final_path}/venv"
|
||||||
|
|
||||||
|
cp ../conf/requirements.txt "$final_path/requirements.txt"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
#run source in a 'sub shell'
|
||||||
|
(
|
||||||
|
set +o nounset
|
||||||
|
source "${final_path}/venv/bin/activate"
|
||||||
|
set -o nounset
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --upgrade wheel pip setuptools
|
||||||
|
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
|
||||||
|
)
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# copy config files
|
||||||
|
# ================================================
|
||||||
|
ynh_script_progression --message="Create project configuration files..."
|
||||||
|
|
||||||
|
gunicorn_conf="$final_path/gunicorn.conf.py"
|
||||||
|
ynh_backup_if_checksum_is_different --file="$gunicorn_conf"
|
||||||
|
cp "../conf/gunicorn.conf.py" "$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$gunicorn_conf"
|
||||||
|
ynh_replace_string --match_string="__PORT__" --replace_string="$port" --target_file="$gunicorn_conf"
|
||||||
|
ynh_store_file_checksum --file="$gunicorn_conf"
|
||||||
|
|
||||||
|
cp ../conf/manage.py "$final_path/manage.py"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$final_path/manage.py"
|
||||||
|
ynh_store_file_checksum --file="$final_path/manage.py"
|
||||||
|
chmod +x "$final_path/manage.py"
|
||||||
|
|
||||||
|
# save old settings file
|
||||||
|
settings="$final_path/settings.py"
|
||||||
|
ynh_backup_if_checksum_is_different --file="$settings"
|
||||||
|
|
||||||
|
cp "../conf/settings.py" "$settings"
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_NAME__" --replace_string="$db_name" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_USER__" --replace_string="$db_user" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__DB_PWD__" --replace_string="$db_pwd" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMIN__" --replace_string="$admin" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__ADMINMAIL__" --replace_string="$admin_mail" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_HOME_PATH__" --replace_string="$final_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__FINAL_WWW_PATH__" --replace_string="$public_path" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__LOG_FILE__" --replace_string="$log_file" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__REDIS_DB__" --replace_string="$redis_db" --target_file="$settings"
|
||||||
|
|
||||||
|
ynh_replace_string --match_string="__DOMAIN__" --replace_string="$domain" --target_file="$settings"
|
||||||
|
ynh_replace_string --match_string="__PATH_URL__" --replace_string="$path_url" --target_file="$settings"
|
||||||
|
|
||||||
|
# Recalculate and store the config file checksum into the app settings
|
||||||
|
ynh_store_file_checksum --file="$settings"
|
||||||
|
|
||||||
|
ynh_backup_if_checksum_is_different --file="$final_path/setup_user.py"
|
||||||
|
cp ../conf/setup_user.py "$final_path/setup_user.py"
|
||||||
|
|
||||||
|
ynh_backup_if_checksum_is_different --file="$final_path/urls.py"
|
||||||
|
cp ../conf/urls.py "$final_path/urls.py"
|
||||||
|
|
||||||
|
ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py"
|
||||||
|
cp ../conf/wsgi.py "$final_path/wsgi.py"
|
||||||
|
|
||||||
|
# Regenerate a fresh local_settings:
|
||||||
|
ynh_backup_if_checksum_is_different --file="$final_path/local_settings.py"
|
||||||
|
ynh_add_config --template="local_settings.py" --destination="$final_path/local_settings.py"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# MIGRATE PYINVENTORY
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="migrate/collectstatic/createadmin..." --weight=10
|
||||||
|
|
||||||
|
cd "$final_path" || exit
|
||||||
|
|
||||||
|
# Just for debugging:
|
||||||
|
./manage.py diffsettings
|
||||||
|
|
||||||
|
./manage.py migrate --no-input
|
||||||
|
./manage.py collectstatic --no-input
|
||||||
|
|
||||||
|
# Create/update Django superuser (set unusable password, because auth done via SSOwat):
|
||||||
|
./manage.py create_superuser --username="$admin" --email="$admin_mail"
|
||||||
|
|
||||||
|
# Check the configuration
|
||||||
|
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
|
||||||
|
./manage.py check --deploy || true
|
||||||
|
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# SETUP LOGROTATE
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Upgrading logrotate configuration..."
|
||||||
|
|
||||||
|
# Use logrotate to manage app-specific logfile(s)
|
||||||
|
ynh_use_logrotate --non-append
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# INTEGRATE SERVICE IN YUNOHOST
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Integrating service in YunoHost..."
|
||||||
|
|
||||||
|
yunohost service add $app --description="Web based management to catalog things" --log="${log_file}"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# GENERIC FINALIZATION
|
||||||
|
#=================================================
|
||||||
|
# SECURE FILES AND DIRECTORIES
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
# Set permissions to app files
|
||||||
|
chown -R "$app:" "$log_path"
|
||||||
|
chown -R "$app:www-data" "$public_path"
|
||||||
|
chown -R "$app:" "$final_path"
|
||||||
|
|
||||||
|
chmod o-rwx "$log_path"
|
||||||
|
chmod o-rwx "$public_path"
|
||||||
|
chmod o-rwx "$final_path"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# Start django-fmd via systemd
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Starting django-fmd's services..." --weight=5
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name="$app" --action="start"
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# RELOAD NGINX
|
||||||
|
#=================================================
|
||||||
|
ynh_script_progression --message="Reloading nginx web server..."
|
||||||
|
|
||||||
|
ynh_systemd_action --service_name=nginx --action=reload
|
||||||
|
|
||||||
|
#=================================================
|
||||||
|
# END OF SCRIPT
|
||||||
|
#=================================================
|
||||||
|
|
||||||
|
ynh_script_progression --message="Upgrade of $app completed" --last
|
17
test_requirements.sh
Executable file
17
test_requirements.sh
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Test to create the python virtual env and install all requirements.
|
||||||
|
# Note: Maybe you didn't have all OS packages installed ;)
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
final_path="./local_test"
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
mkdir -p "${final_path}/"
|
||||||
|
python3 -m venv "${final_path}/venv"
|
||||||
|
source "${final_path}/venv/bin/activate"
|
||||||
|
|
||||||
|
$final_path/venv/bin/pip install --upgrade wheel pip
|
||||||
|
$final_path/venv/bin/pip install --no-deps -r "./conf/requirements.txt"
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
176
tests/test_django_project.py
Normal file
176
tests/test_django_project.py
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from bx_django_utils.test_utils.html_assertion import HtmlAssertionMixin
|
||||||
|
from django.conf import LazySettings, settings
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.test import override_settings
|
||||||
|
from django.test.testcases import TestCase
|
||||||
|
from django.urls import NoReverseMatch
|
||||||
|
from django.urls.base import reverse
|
||||||
|
from django_yunohost_integration.test_utils import generate_basic_auth
|
||||||
|
from django_yunohost_integration.views import request_media_debug_view
|
||||||
|
|
||||||
|
import findmydevice
|
||||||
|
|
||||||
|
|
||||||
|
@override_settings(DEBUG=False)
|
||||||
|
class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
# Always start a fresh session:
|
||||||
|
self.client = self.client_class()
|
||||||
|
|
||||||
|
def test_settings(self):
|
||||||
|
assert isinstance(settings, LazySettings)
|
||||||
|
assert settings.configured is True
|
||||||
|
|
||||||
|
assert settings.PATH_URL == 'app_path'
|
||||||
|
|
||||||
|
def assert_path(path, end_text):
|
||||||
|
assert isinstance(path, Path)
|
||||||
|
path = str(path)
|
||||||
|
assert path.endswith(end_text)
|
||||||
|
|
||||||
|
assert_path(settings.FINAL_HOME_PATH, '/local_test/opt_yunohost')
|
||||||
|
assert_path(settings.FINAL_WWW_PATH, '/local_test/var_www')
|
||||||
|
assert_path(settings.LOG_FILE, '/local_test/var_log_django-fmd.log')
|
||||||
|
|
||||||
|
assert settings.ROOT_URLCONF == 'urls'
|
||||||
|
|
||||||
|
def test_urls(self):
|
||||||
|
assert reverse('admin:index') == '/app_path/admin/'
|
||||||
|
|
||||||
|
# The django_yunohost_integration debug view should not be available:
|
||||||
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse(request_media_debug_view)
|
||||||
|
|
||||||
|
def test_auth(self):
|
||||||
|
# SecurityMiddleware should redirects all non-HTTPS requests to HTTPS:
|
||||||
|
assert settings.SECURE_SSL_REDIRECT is True
|
||||||
|
response = self.client.get('/app_path/', secure=False)
|
||||||
|
self.assertRedirects(
|
||||||
|
response,
|
||||||
|
status_code=301, # permanent redirect
|
||||||
|
expected_url='https://testserver/app_path/',
|
||||||
|
fetch_redirect_response=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get('/app_path/', secure=True)
|
||||||
|
self.assertRedirects(
|
||||||
|
response, expected_url='/app_path/group_management/', fetch_redirect_response=False
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get('/app_path/group_management/', secure=True)
|
||||||
|
self.assertRedirects(
|
||||||
|
response,
|
||||||
|
expected_url='/app_path/admin/login/?next=/app_path/group_management/',
|
||||||
|
fetch_redirect_response=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.get('/app_path/admin/', secure=True)
|
||||||
|
self.assertRedirects(
|
||||||
|
response,
|
||||||
|
expected_url='/app_path/admin/login/?next=/app_path/admin/',
|
||||||
|
fetch_redirect_response=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
@override_settings(SECURE_SSL_REDIRECT=False)
|
||||||
|
def test_create_unknown_user(self):
|
||||||
|
assert User.objects.count() == 0
|
||||||
|
|
||||||
|
self.client.cookies['SSOwAuthUser'] = 'test'
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
path='/app_path/admin/',
|
||||||
|
HTTP_REMOTE_USER='test',
|
||||||
|
HTTP_AUTH_USER='test',
|
||||||
|
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert User.objects.count() == 1
|
||||||
|
user = User.objects.first()
|
||||||
|
assert user.username == 'test'
|
||||||
|
assert user.is_active is True
|
||||||
|
assert user.is_staff is True # Set by: django_yunohost_integration
|
||||||
|
assert user.is_superuser is False
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
self.assert_html_parts(
|
||||||
|
response,
|
||||||
|
parts=(
|
||||||
|
(
|
||||||
|
'<title>Site administration | django-fmd'
|
||||||
|
f' v{findmydevice.__version__}</title>'
|
||||||
|
),
|
||||||
|
'<strong>test</strong>',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
@override_settings(SECURE_SSL_REDIRECT=False)
|
||||||
|
def test_wrong_auth_user(self):
|
||||||
|
assert User.objects.count() == 0
|
||||||
|
|
||||||
|
self.client.cookies['SSOwAuthUser'] = 'test'
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
path='/app_path/admin/',
|
||||||
|
HTTP_REMOTE_USER='test',
|
||||||
|
HTTP_AUTH_USER='foobar', # <<< wrong user name
|
||||||
|
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert User.objects.count() == 1
|
||||||
|
user = User.objects.first()
|
||||||
|
assert user.username == 'test'
|
||||||
|
assert user.is_active is True
|
||||||
|
assert user.is_staff is True # Set by: django_yunohost_integration
|
||||||
|
assert user.is_superuser is False
|
||||||
|
|
||||||
|
assert response.status_code == 403 # Forbidden
|
||||||
|
|
||||||
|
@override_settings(SECURE_SSL_REDIRECT=False)
|
||||||
|
def test_wrong_cookie(self):
|
||||||
|
assert User.objects.count() == 0
|
||||||
|
|
||||||
|
self.client.cookies['SSOwAuthUser'] = 'foobar' # <<< wrong user name
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
path='/app_path/admin/',
|
||||||
|
HTTP_REMOTE_USER='test',
|
||||||
|
HTTP_AUTH_USER='test',
|
||||||
|
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
|
||||||
|
)
|
||||||
|
|
||||||
|
assert User.objects.count() == 1
|
||||||
|
user = User.objects.first()
|
||||||
|
assert user.username == 'test'
|
||||||
|
assert user.is_active is True
|
||||||
|
assert user.is_staff is True # Set by: django_yunohost_integration
|
||||||
|
assert user.is_superuser is False
|
||||||
|
|
||||||
|
assert response.status_code == 403 # Forbidden
|
||||||
|
|
||||||
|
@override_settings(SECURE_SSL_REDIRECT=False)
|
||||||
|
def test_wrong_authorization_user(self):
|
||||||
|
assert User.objects.count() == 0
|
||||||
|
|
||||||
|
self.client.cookies['SSOwAuthUser'] = 'test'
|
||||||
|
|
||||||
|
response = self.client.get(
|
||||||
|
path='/app_path/admin/',
|
||||||
|
HTTP_REMOTE_USER='test',
|
||||||
|
HTTP_AUTH_USER='test',
|
||||||
|
HTTP_AUTHORIZATION=generate_basic_auth(
|
||||||
|
username='foobar', password='test123'
|
||||||
|
), # <<< wrong user name
|
||||||
|
)
|
||||||
|
|
||||||
|
assert User.objects.count() == 1
|
||||||
|
user = User.objects.first()
|
||||||
|
assert user.username == 'test'
|
||||||
|
assert user.is_active is True
|
||||||
|
assert user.is_staff is True # Set by: django_yunohost_integration
|
||||||
|
assert user.is_superuser is False
|
||||||
|
|
||||||
|
assert response.status_code == 403 # Forbidden
|
89
tests/test_project_setup.py
Normal file
89
tests/test_project_setup.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import difflib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from bx_django_utils.filename import clean_filename
|
||||||
|
from bx_py_utils.path import assert_is_dir, assert_is_file
|
||||||
|
|
||||||
|
import findmydevice
|
||||||
|
|
||||||
|
|
||||||
|
PACKAGE_ROOT = Path(__file__).parent.parent
|
||||||
|
|
||||||
|
|
||||||
|
def assert_file_contains_string(file_path, string):
|
||||||
|
with file_path.open('r') as f:
|
||||||
|
for line in f:
|
||||||
|
if string in line:
|
||||||
|
return
|
||||||
|
raise AssertionError(f'File {file_path} does not contain {string!r} !')
|
||||||
|
|
||||||
|
|
||||||
|
def test_version():
|
||||||
|
version = findmydevice.__version__
|
||||||
|
|
||||||
|
assert_file_contains_string(
|
||||||
|
file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh'
|
||||||
|
)
|
||||||
|
assert_file_contains_string(
|
||||||
|
file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def poetry_check_output(*args):
|
||||||
|
poerty_bin = shutil.which('poetry')
|
||||||
|
|
||||||
|
output = subprocess.check_output(
|
||||||
|
(poerty_bin,) + args,
|
||||||
|
universal_newlines=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 = Path('conf', 'requirements.txt')
|
||||||
|
assert_is_file(requirements_txt)
|
||||||
|
|
||||||
|
output = poetry_check_output('export', '-f', 'requirements.txt')
|
||||||
|
assert 'Warning' not in output
|
||||||
|
|
||||||
|
current_content = requirements_txt.read_text()
|
||||||
|
|
||||||
|
diff = '\n'.join(
|
||||||
|
difflib.unified_diff(
|
||||||
|
current_content.splitlines(),
|
||||||
|
output.splitlines(),
|
||||||
|
fromfile=str(requirements_txt),
|
||||||
|
tofile='FRESH EXPORT',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
print(diff)
|
||||||
|
assert diff == '', f'{requirements_txt} is not up-to-date! (Hint: call: "make update")'
|
||||||
|
|
||||||
|
|
||||||
|
def test_screenshot_filenames():
|
||||||
|
"""
|
||||||
|
https://forum.yunohost.org/t/yunohost-bot-cant-handle-spaces-in-screenshots/19483
|
||||||
|
"""
|
||||||
|
screenshot_path = PACKAGE_ROOT / 'doc' / 'screenshots'
|
||||||
|
assert_is_dir(screenshot_path)
|
||||||
|
renamed = []
|
||||||
|
for file_path in screenshot_path.iterdir():
|
||||||
|
file_name = file_path.name
|
||||||
|
cleaned_name = clean_filename(file_name)
|
||||||
|
if cleaned_name != file_name:
|
||||||
|
new_path = file_path.with_name(cleaned_name)
|
||||||
|
file_path.rename(new_path)
|
||||||
|
renamed.append(f'{file_name!r} renamed to {cleaned_name!r}')
|
||||||
|
assert not renamed, f'Bad screenshots file names found: {", ".join(renamed)}'
|
8
tests/test_utils.py
Normal file
8
tests/test_utils.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from unittest.case import TestCase
|
||||||
|
|
||||||
|
from django_yunohost_integration.test_utils import generate_basic_auth
|
||||||
|
|
||||||
|
|
||||||
|
class TestUtilsTestCase(TestCase):
|
||||||
|
def test_generate_basic_auth(self):
|
||||||
|
assert generate_basic_auth(username='test', password='test123') == 'basic dGVzdDp0ZXN0MTIz'
|
Loading…
Reference in a new issue