Merge pull request #27 from YunoHost-Apps/testing

master <- testing
This commit is contained in:
Jens Diemer 2022-09-19 13:19:08 +02:00 committed by GitHub
commit 09059ea906
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 1744 additions and 1494 deletions

View file

@ -10,7 +10,7 @@ trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[*.py] [*.py]
line_length = 119 max_line_length = 100
[{Makefile,**.mk}] [{Makefile,**.mk}]
indent_style = tab indent_style = tab
@ -18,4 +18,3 @@ insert_final_newline = false
[*.yml] [*.yml]
indent_style = tab indent_style = tab
indent_size = 4

View file

@ -22,9 +22,14 @@ jobs:
with: with:
python-version: '${{ matrix.python-version }}' python-version: '${{ matrix.python-version }}'
- uses: actions/cache@v2
with:
path: ~/.cache/
key: dot-cache-files
- name: 'Install package' - name: 'Install package'
run: | run: |
pip3 install poetry make install-poetry
make install make install
- name: 'List installed packages' - name: 'List installed packages'
@ -35,5 +40,12 @@ jobs:
run: | run: |
make pytest make pytest
- name: 'Run Safety check'
run: |
make safety
- name: 'Upload coverage report' - name: 'Upload coverage report'
run: bash <(curl -s https://codecov.io/bash) uses: codecov/codecov-action@v2
with:
fail_ci_if_error: false
verbose: true

4
.gitignore vendored
View file

@ -3,6 +3,10 @@
!.editorconfig !.editorconfig
!.flake8 !.flake8
!.gitignore !.gitignore
!.safety-policy.yml
!/doc/screenshots/.gitkeep
__pycache__ __pycache__
secret.txt secret.txt
/local_test/ /local_test/

12
.safety-policy.yml Normal file
View file

@ -0,0 +1,12 @@
# Safety Security and License Configuration file
security:
ignore-vulnerabilities: # Here you can list multiple specific vulnerabilities you want to ignore (optionally for a time period)
44715:
reason: Numpy >=1.22.0 needs Python 3.8
expires: '2022-12-31' # datetime string - date this ignore will expire, best practice to use this variable
44716:
reason: Numpy >=1.22.0 needs Python 3.8
expires: '2022-12-31' # datetime string - date this ignore will expire, best practice to use this variable
44717:
reason: Numpy >=1.22.0 needs Python 3.8
expires: '2022-12-31' # datetime string - date this ignore will expire, best practice to use this variable

View file

@ -1,5 +1,5 @@
SHELL := /bin/bash SHELL := /bin/bash
MAX_LINE_LENGTH := 119 MAX_LINE_LENGTH := 100
all: help all: help
@ -17,17 +17,23 @@ check-poetry:
fi fi
install-poetry: ## install or update poetry install-poetry: ## install or update poetry
pip3 install -U pip curl -sSL https://install.python-poetry.org | python3 -
pip3 install -U poetry
install: check-poetry ## install project via poetry install: check-poetry ## install project via poetry
poetry install poetry install
update: install-poetry ## update the sources and installation and generate "conf/requirements.txt" update: check-poetry ## update the sources and installation and generate "conf/requirements.txt"
poetry run pip install -U pip poetry update -v
poetry update
poetry export -f requirements.txt --output conf/requirements.txt poetry export -f requirements.txt --output conf/requirements.txt
lint: ## Run code formatters and linter
poetry run isort --check-only .
poetry run flake8 .
fix-code-style: ## Fix code formatting
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 tox-listenvs: check-poetry ## List all tox test environments
poetry run tox --listenvs poetry run tox --listenvs
@ -35,7 +41,7 @@ tox: check-poetry ## Run pytest via tox with all environments
poetry run tox poetry run tox
pytest: install ## Run pytest pytest: install ## Run pytest
poetry run python3 ./run_pytest.py poetry run pytest
local-test: install ## Run local_test.py to run the project locally local-test: install ## Run local_test.py to run the project locally
poetry run python3 ./local_test.py poetry run python3 ./local_test.py
@ -43,6 +49,8 @@ local-test: install ## Run local_test.py to run the project locally
local-diff-settings: ## Run "manage.py diffsettings" with local test local-diff-settings: ## Run "manage.py diffsettings" with local test
poetry run python3 local_test/opt_yunohost/manage.py diffsettings poetry run python3 local_test/opt_yunohost/manage.py diffsettings
safety: ## Run https://github.com/pyupio/safety
poetry run safety check --full-report
############################################################################## ##############################################################################

View file

@ -5,7 +5,7 @@ It shall NOT be edited by hand.
# django-for-runners for YunoHost # django-for-runners for YunoHost
[![Integration level](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg) [![Integration level](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) ![Working status](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![Maintenance status](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg)
[![Install django-for-runners with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners) [![Install django-for-runners with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
*[Lire ce readme en français.](./README_fr.md)* *[Lire ce readme en français.](./README_fr.md)*
@ -33,15 +33,14 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole) More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
**Shipped version:** 0.13.0~ynh2 **Shipped version:** 0.15.0~ynh2
## Screenshots ## Screenshots
![](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png) ![Screenshot of django-for-runners](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png)
![](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png) ![Screenshot of django-for-runners](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png)
![](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png) ![Screenshot of django-for-runners](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png)
## Disclaimers / important information ## Disclaimers / important information
@ -200,20 +199,21 @@ Notes:
## Documentation and resources ## Documentation and resources
* Official app website: https://github.com/jedie/django-for-runners * Official app website: <https://github.com/jedie/django-for-runners>
* Upstream app code repository: https://github.com/jedie/django-for-runners * Upstream app code repository: <https://github.com/jedie/django-for-runners>
* YunoHost documentation for this app: https://yunohost.org/app_django-for-runners * YunoHost documentation for this app: <https://yunohost.org/app_django-for-runners>
* Report a bug: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues * Report a bug: <https://github.com/YunoHost-Apps/django-for-runners_ynh/issues>
## Developer info ## Developer info
Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing). Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing).
To try the testing branch, please proceed like that. To try the testing branch, please proceed like that.
```
``` bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
or or
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
``` ```
**More info regarding app packaging:** https://yunohost.org/packaging_apps **More info regarding app packaging:** <https://yunohost.org/packaging_apps>

View file

@ -1,10 +1,14 @@
<!--
N.B.: This README was automatically generated by https://github.com/YunoHost/apps/tree/master/tools/README-generator
It shall NOT be edited by hand.
-->
# django-for-runners pour YunoHost # django-for-runners pour YunoHost
[![Niveau d'intégration](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg) [![Niveau d'intégration](https://dash.yunohost.org/integration/django-for-runners.svg)](https://dash.yunohost.org/appci/app/django-for-runners) ![Statut du fonctionnement](https://ci-apps.yunohost.org/ci/badges/django-for-runners.status.svg) ![Statut de maintenance](https://ci-apps.yunohost.org/ci/badges/django-for-runners.maintain.svg)
[![Installer django-for-runners avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners) [![Installer django-for-runners avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=django-for-runners)
*[Read this readme in english.](./README.md)* *[Read this readme in english.](./README.md)*
*[Lire ce readme en français.](./README_fr.md)*
> *Ce package vous permet d'installer django-for-runners rapidement et simplement sur un serveur YunoHost. > *Ce package vous permet d'installer django-for-runners rapidement et simplement sur un serveur YunoHost.
Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.* Si vous n'avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l'installer et en profiter.*
@ -29,15 +33,14 @@ This package for YunoHost used [django-yunohost-integration](https://github.com/
More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole) More screenshots are here: [jedie.github.io/tree/master/screenshots/django-for-runners](https://github.com/jedie/jedie.github.io/tree/master/screenshots/django-for-runners/README.creole)
**Version incluse :** 0.13.0~ynh2 **Version incluse :** 0.15.0~ynh2
## Captures d'écran ## Captures d'écran
![](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png) ![Capture d'écran de django-for-runners](./doc/screenshots/for_runers_v060_2018_07_31_gpx_track.png)
![](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png) ![Capture d'écran de django-for-runners](./doc/screenshots/for_runners_v060_2018_07_19_event_costs.png)
![](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png) ![Capture d'écran de django-for-runners](./doc/screenshots/for_runners_v040_2018_6_26_gpx_info.png)
## Avertissements / informations importantes ## Avertissements / informations importantes
@ -196,20 +199,21 @@ Notes:
## Documentations et ressources ## Documentations et ressources
* Site officiel de l'app : https://github.com/jedie/django-for-runners * Site officiel de l'app : <https://github.com/jedie/django-for-runners>
* Dépôt de code officiel de l'app : https://github.com/jedie/django-for-runners * Dépôt de code officiel de l'app : <https://github.com/jedie/django-for-runners>
* Documentation YunoHost pour cette app : https://yunohost.org/app_django-for-runners * Documentation YunoHost pour cette app : <https://yunohost.org/app_django-for-runners>
* Signaler un bug : https://github.com/YunoHost-Apps/django-for-runners_ynh/issues * Signaler un bug : <https://github.com/YunoHost-Apps/django-for-runners_ynh/issues>
## Informations pour les développeurs ## Informations pour les développeurs
Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing). Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing).
Pour essayer la branche testing, procédez comme suit. Pour essayer la branche testing, procédez comme suit.
```
``` bash
sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug sudo yunohost app install https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
ou ou
sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug sudo yunohost app upgrade django-for-runners -u https://github.com/YunoHost-Apps/django-for-runners_ynh/tree/testing --debug
``` ```
**Plus d'infos sur le packaging d'applications :** https://yunohost.org/packaging_apps **Plus d'infos sur le packaging d'applications :** <https://yunohost.org/packaging_apps>

View file

@ -16,7 +16,7 @@
setup_sub_dir=1 setup_sub_dir=1
setup_root=1 setup_root=1
setup_nourl=0 setup_nourl=0
setup_private=1 setup_private=0
setup_public=1 setup_public=1
upgrade=1 upgrade=1
backup_restore=1 backup_restore=1

View file

@ -17,4 +17,4 @@ accesslog = '__LOG_FILE__'
errorlog = '__LOG_FILE__' errorlog = '__LOG_FILE__'
# https://docs.gunicorn.org/en/latest/settings.html#pidfile # https://docs.gunicorn.org/en/latest/settings.html#pidfile
pidfile = '__FINAL_HOME_PATH__/gunicorn.pid' pidfile = '__FINALPATH__/gunicorn.pid'

View file

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

View file

@ -1,17 +1,11 @@
location __PATH__/static/ { location __PATH__/static/ {
# Django static files # Service static files by nginx
# e.g.: /var/www/$app/static
alias __PUBLIC_PATH__/static/; alias __PUBLIC_PATH__/static/;
expires 30d; expires 30d;
} }
# TODO: django-sendfile2:
#location __PATH__/media/ {
# # DATA_DIR/media/
# alias __PUBLIC_PATH__/media/;
# expires 30d;
#}
location __PATH__/ { location __PATH__/ {
# https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf # https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# Please do not modify this file, it will be reset at the next update. # Please do not modify this file, it will be reset at the next update.
# You can edit the file __FINAL_HOME_PATH__/local_settings.py and add/modify the settings you need. # You can edit the file __FINALPATH__/local_settings.py and add/modify the settings you need.
# The parameters you add in local_settings.py will overwrite these, # The parameters you add in local_settings.py will overwrite these,
# but you can use the options and documentation in this file to find out what can be done. # but you can use the options and documentation in this file to find out what can be done.
@ -11,35 +11,42 @@
from pathlib import Path as __Path from pathlib import Path as __Path
from django_yunohost_integration.base_settings import * # noqa from django_yunohost_integration.base_settings import * # noqa:F401,F403
from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret from django_yunohost_integration.secret_key import get_or_create_secret as __get_or_create_secret
from for_runners_project.settings.base import * # noqa
DEBUG = False # Don't turn DEBUG on in production! from for_runners_project.settings.base import * # noqa isort:skip
from django_yunohost_integration.base_settings import LOGGING # noqa:F401 isort:skip
# ----------------------------------------------------------------------------- FINALPATH = __Path('__FINALPATH__') # /opt/yunohost/$app
assert FINALPATH.is_dir(), f'Directory not exists: {FINALPATH}'
FINAL_HOME_PATH = __Path('__FINAL_HOME_PATH__') # /opt/yunohost/$app PUBLIC_PATH = __Path('__PUBLIC_PATH__') # /var/www/$app
assert FINAL_HOME_PATH.is_dir(), f'Directory not exists: {FINAL_HOME_PATH}' assert PUBLIC_PATH.is_dir(), f'Directory not exists: {PUBLIC_PATH}'
FINAL_WWW_PATH = __Path('__FINAL_WWW_PATH__') # /var/www/$app LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django_example_ynh.log
assert FINAL_WWW_PATH.is_dir(), f'Directory not exists: {FINAL_WWW_PATH}'
LOG_FILE = __Path('__LOG_FILE__') # /var/log/$app/django-for-runners.log
assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}' assert LOG_FILE.is_file(), f'File not exists: {LOG_FILE}'
PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH PATH_URL = '__PATH_URL__' # $YNH_APP_ARG_PATH
PATH_URL = PATH_URL.strip('/') PATH_URL = PATH_URL.strip('/')
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# config_panel.toml settings:
ROOT_URLCONF = 'urls' # /opt/yunohost/django-for-runners/ynh_urls.py DEBUG_ENABLED = '__DEBUG_ENABLED__'
DEBUG = bool(int(DEBUG_ENABLED))
LOG_LEVEL = '__LOG_LEVEL__'
ADMIN_EMAIL = '__ADMIN_EMAIL__'
DEFAULT_FROM_EMAIL = '__DEFAULT_FROM_EMAIL__'
# -----------------------------------------------------------------------------
# Function that will be called to finalize a user profile: # Function that will be called to finalize a user profile:
YNH_SETUP_USER = 'setup_user.setup_project_user' YNH_SETUP_USER = 'setup_user.setup_project_user'
SECRET_KEY = __get_or_create_secret(FINAL_HOME_PATH / 'secret.txt') # /opt/yunohost/$app/secret.txt SECRET_KEY = __get_or_create_secret(FINALPATH / 'secret.txt') # /opt/yunohost/$app/secret.txt
INSTALLED_APPS.append('django_yunohost_integration') INSTALLED_APPS.append('django_yunohost_integration')
@ -65,10 +72,12 @@ LOGIN_URL = '/yunohost/sso/'
LOGOUT_REDIRECT_URL = '/yunohost/sso/' LOGOUT_REDIRECT_URL = '/yunohost/sso/'
# /yunohost/sso/?action=logout # /yunohost/sso/?action=logout
ROOT_URLCONF = 'urls' # .../conf/urls.py
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
ADMINS = (('__ADMIN__', '__ADMINMAIL__'),) ADMINS = (('__ADMIN__', ADMIN_EMAIL),)
MANAGERS = ADMINS MANAGERS = ADMINS
@ -95,11 +104,10 @@ EMAIL_SUBJECT_PREFIX = f'[{SITE_TITLE}] '
# E-mail address that error messages come from. # E-mail address that error messages come from.
SERVER_EMAIL = 'noreply@__DOMAIN__' SERVER_EMAIL = ADMIN_EMAIL
# Default email address to use for various automated correspondence from # Default email address to use for various automated correspondence from
# the site managers. Used for registration emails. # the site managers. Used for registration emails.
DEFAULT_FROM_EMAIL = '__ADMINMAIL__'
# List of URLs your site is supposed to serve # List of URLs your site is supposed to serve
ALLOWED_HOSTS = ['__DOMAIN__'] ALLOWED_HOSTS = ['__DOMAIN__']
@ -131,47 +139,25 @@ else:
STATIC_URL = '/static/' STATIC_URL = '/static/'
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
STATIC_ROOT = str(FINAL_WWW_PATH / 'static') STATIC_ROOT = str(PUBLIC_PATH / 'static')
MEDIA_ROOT = str(FINAL_WWW_PATH / 'media') MEDIA_ROOT = str(PUBLIC_PATH / 'media')
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
LOGGING = { # Set log file to e.g.: /var/log/$app/$app.log
'version': 1, LOGGING['handlers']['log_file']['filename'] = str(LOG_FILE)
'disable_existing_loggers': True,
'formatters': { # Example how to add logging to own app:
'verbose': { LOGGING['loggers']['for_runners'] = {
'format': '{asctime} {levelname} {name} {module}.{funcName} {message}', 'handlers': ['syslog', 'log_file', 'mail_admins'],
'style': '{', 'level': 'INFO',
}, 'propagate': False,
},
'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_ynh': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
'for_runners': {'handlers': ['log_file', 'mail_admins'], 'level': 'INFO', 'propagate': False},
},
} }
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
try: try:
from local_settings import * # noqa from local_settings import * # noqa:F401,F403
except ImportError: except ImportError:
pass pass

View file

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

View file

@ -1,5 +1,4 @@
from django.conf import settings from django.conf import settings
from django.conf.urls import static
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path
@ -12,12 +11,9 @@ if settings.PATH_URL:
urlpatterns = [ urlpatterns = [
path(f'{settings.PATH_URL}/', admin.site.urls), path(f'{settings.PATH_URL}/', admin.site.urls),
path(f'{settings.PATH_URL}/media/<slug:user_name>/<path:path>', UserMediaView.as_view()), path(f'{settings.PATH_URL}/media/<slug:user_name>/<path:path>', UserMediaView.as_view()),
# TODO: https://github.com/jedie/django-for-runners/issues/25 # TODO: https://github.com/jedie/django-for-runners/issues/25
# path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')), # path(settings.MEDIA_URL.lstrip('/'), include('django_tools.serve_media_app.urls')),
] ]
if settings.SERVE_FILES:
urlpatterns += static.static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
else: else:
# Installed to domain root, without a path prefix # Installed to domain root, without a path prefix
# Just use the default project urls.py # Just use the default project urls.py

35
config_panel.toml Normal file
View file

@ -0,0 +1,35 @@
version = "1.0"
[main]
name = "django_example_ynh configuration"
services = ["__APP__"]
[main.config]
name = "Configuration Options"
[main.config.default_from_email]
ask = "from email"
type = "email"
help = "Default email address to use for various automated emails."
bind = "default_from_email:__FINALPATH__/settings.py"
[main.config.admin_email]
ask = "ADMIN email"
type = "email"
help = "EMail address for error emails."
bind = "admin_email:__FINALPATH__/settings.py"
[main.config.debug_enabled]
ask = "DEBUG mode"
type = "boolean"
yes = "1"
no = "0"
help = "Should be never enabled in production!"
bind = "debug_enabled:__FINALPATH__/settings.py"
[main.config.log_level]
type = "string"
ask = "Log Level"
choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
default = "WARNING"
bind = "log_level:__FINALPATH__/settings.py"

0
doc/screenshots/.gitkeep Normal file
View file

View file

@ -22,6 +22,9 @@ def main():
django_settings_path=BASE_PATH / 'conf' / 'settings.py', django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test', destination=BASE_PATH / 'local_test',
runserver=True, runserver=True,
extra_replacements={
'__DEBUG_ENABLED__': '1',
},
) )

View file

@ -5,7 +5,7 @@
"description": { "description": {
"en": "Store your GPX tracks of your running (or other sports activity)" "en": "Store your GPX tracks of your running (or other sports activity)"
}, },
"version": "0.13.0~ynh2", "version": "0.15.0~ynh2",
"url": "https://github.com/jedie/django-for-runners", "url": "https://github.com/jedie/django-for-runners",
"upstream": { "upstream": {
"license": "GPL-3.0", "license": "GPL-3.0",
@ -19,11 +19,11 @@
}, },
"previous_maintainers": [], "previous_maintainers": [],
"requirements": { "requirements": {
"yunohost": ">= 4.0" "yunohost": ">= 4.4"
}, },
"multi_instance": true, "multi_instance": true,
"services": [ "services": [
"nginx" "nginx", "postgresql", "redis"
], ],
"arguments": { "arguments": {
"install" : [ "install" : [
@ -40,7 +40,16 @@
{ {
"name": "admin", "name": "admin",
"type": "user" "type": "user"
} },
{
"name": "is_public",
"type": "boolean",
"help": {
"en": "Any YunoHost user and anonymous people from the web will be able to access the application",
"fr": "Tout utilisateur YunoHost et les personnes anonymes pourront accéder à l'application"
},
"default": false
}
] ]
} }
} }

1502
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,40 +1,32 @@
[tool.poetry] [tool.poetry]
name = "for_runners_ynh" name = "for_runners_ynh"
version = "0.13.0~ynh2" version = "0.15.0+ynh2"
description = "Test for_runners_ynh via local_test.py" description = "Test for_runners_ynh via local_test.py"
authors = ["JensDiemer <git@jensdiemer.de>"] authors = ["JensDiemer <git@jensdiemer.de>"]
license = "GPL" license = "GPL"
[tool.poetry.dependencies] [tool.poetry.dependencies]
# Keep Python 3.7 until Yunohost contains a newer Python Version ;) python = ">=3.7,<4.0.0" # TODO: Update to >=3.8 after YunoHost updates to Bullseye
python = ">=3.7,<4.0.0" django_yunohost_integration = {version = ">=0.4.0", extras = ["ynh"]}
django-for-runners = ">=0.13.0"
# Note: "ynh" extras will install gunicorn, psycopg2, django-redis and django-axes
django_yunohost_integration = {version = ">=v0.2.0", extras = ["ynh"]}
# TODO: Update psycopg2 after django-for-runners updates Django >2.2 update django-for-runners = ">=0.15.0"
# See: https://github.com/psycopg/psycopg2/issues/1293
psycopg2 = "<2.9" # https://www.psycopg.org/docs/install.html#build-prerequisites
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
bx_py_utils = "*" bx_py_utils = "*" # https://github.com/boxine/bx_py_utils
bx_django_utils = "*" bx_django_utils = "*" # https://github.com/boxine/bx_django_utils
tox = "*" tox = "*"
pytest = "*" pytest = "*"
pytest-cov = "*" pytest-cov = "*"
pytest-django = "*" pytest-django = "*"
pytest-darker = "*" # https://github.com/akaihola/pytest-darker pytest-darker = "*" # https://github.com/akaihola/pytest-darker
pytest-flake8 = "*"
pytest-isort = "*"
coveralls = "*" coveralls = "*"
isort = "*" isort = "*"
flake8 = "*" flake8 = "*"
flynt = "*" EditorConfig = "*" # https://github.com/editorconfig/editorconfig-core-py
darker = "*" # https://github.com/akaihola/darker safety = "*" # https://github.com/pyupio/safety
pyupgrade = "*"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
@ -54,16 +46,12 @@ lint = [
log_level = "INFO" log_level = "INFO"
[tool.flynt]
line_length = 100
[tool.isort] [tool.isort]
# https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format # https://pycqa.github.io/isort/docs/configuration/config_files/#pyprojecttoml-preferred-format
atomic=true atomic=true
profile='black' profile='black'
skip_glob=["*/htmlcov/*","*/migrations/*","*/local_test/*"]
line_length=100 line_length=100
skip_glob=["*/htmlcov/*","*/migrations/*"]
known_first_party=["for_runners"] known_first_party=["for_runners"]
lines_after_imports=2 lines_after_imports=2
@ -71,7 +59,7 @@ lines_after_imports=2
[tool.pytest.ini_options] [tool.pytest.ini_options]
# https://docs.pytest.org/en/latest/customize.html#pyproject-toml # https://docs.pytest.org/en/latest/customize.html#pyproject-toml
minversion = "6.0" minversion = "6.0"
norecursedirs = ".* .git __pycache__ conf coverage* dist htmlcov" norecursedirs = ".* .git __pycache__ conf local_test coverage* dist htmlcov"
# sometimes helpfull "addopts" arguments: # sometimes helpfull "addopts" arguments:
# -vv # -vv
# --verbose # --verbose
@ -89,21 +77,22 @@ addopts = """
--no-cov-on-fail --no-cov-on-fail
--showlocals --showlocals
--darker --darker
--flake8
--isort
--doctest-modules --doctest-modules
--failed-first --failed-first
--last-failed-no-failures all
--new-first --new-first
""" """
# TODO: --mypy
[tool.coverage.run]
omit = [".*"]
[tool.tox] [tool.tox]
# https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini # https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini
legacy_tox_ini = """ legacy_tox_ini = """
[tox] [tox]
isolated_build = True isolated_build = True
envlist = px310,py39,py38,py37 envlist = py{37,38,39,310}
skip_missing_interpreters = True skip_missing_interpreters = True
[testenv] [testenv]

View file

@ -1,25 +0,0 @@
"""
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()

View file

@ -11,6 +11,22 @@ admin=$YNH_APP_ARG_ADMIN
is_public=$YNH_APP_ARG_IS_PUBLIC is_public=$YNH_APP_ARG_IS_PUBLIC
app=$YNH_APP_INSTANCE_NAME app=$YNH_APP_INSTANCE_NAME
#=================================================
# ARGUMENTS FROM CONFIG PANEL
#=================================================
# 'debug_enabled' -> '__DEBUG_ENABLED__' -> settings.DEBUG
debug_enabled="0"
# 'log_level' -> '__LOG_LEVEL__' -> settings.LOG_LEVEL
log_level="WARNING"
# 'admin_email' -> '__ADMIN_EMAIL__' add in settings.ADMINS
admin_email="${admin}@${domain}"
# 'default_from_email' -> '__DEFAULT_FROM_EMAIL__' -> settings.DEFAULT_FROM_EMAIL
default_from_email="${app}@${domain}"
#================================================= #=================================================
# SET CONSTANTS # SET CONSTANTS
#================================================= #=================================================
@ -18,7 +34,7 @@ app=$YNH_APP_INSTANCE_NAME
public_path=/var/www/$app public_path=/var/www/$app
final_path=/opt/yunohost/$app final_path=/opt/yunohost/$app
log_path=/var/log/$app log_path=/var/log/$app
log_file="${log_path}/django-for-runners.log" log_file="${log_path}/${app}.log"
#================================================= #=================================================
# COMMON VARIABLES # COMMON VARIABLES
@ -78,17 +94,3 @@ ynh_redis_remove_db() {
redis-cli -n "$db" flushall 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
}

View file

@ -6,6 +6,9 @@
# IMPORT GENERIC HELPERS # IMPORT GENERIC HELPERS
#================================================= #=================================================
YNH_APP_ARG_DOMAIN=$YNH_APP_NEW_DOMAIN
YNH_APP_ARG_PATH=$YNH_APP_NEW_PATH
source _common.sh source _common.sh
source /usr/share/yunohost/helpers source /usr/share/yunohost/helpers
@ -25,16 +28,26 @@ new_path=$YNH_APP_NEW_PATH
ynh_script_progression --message="Loading installation settings..." ynh_script_progression --message="Loading installation settings..."
admin=$(ynh_app_setting_get --app="$app" --key=admin) admin=$(ynh_app_setting_get --app="$app" --key=admin)
is_public=$(ynh_app_setting_get --app="$app" --key=is_public)
public_path=$(ynh_app_setting_get --app="$app" --key=public_path) public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
final_path=$(ynh_app_setting_get --app="$app" --key=final_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
log_path=$(ynh_app_setting_get --app="$app" --key=log_path) log_path=$(ynh_app_setting_get --app="$app" --key=log_path)
port=$(ynh_app_setting_get --app="$app" --key=port) port=$(ynh_app_setting_get --app="$app" --key=port)
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
admin_mail=$(ynh_user_get_info "$admin" mail) db_name=$(ynh_sanitize_dbid --db_name="$app")
db_user=$db_name
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db) redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
#-------------------------------------------------
# config_panel.toml settings:
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#================================================= #=================================================
@ -73,7 +86,7 @@ fi
#================================================= #=================================================
# STOP SYSTEMD SERVICE # STOP SYSTEMD SERVICE
#================================================= #=================================================
ynh_script_progression --message="Stopping systemd services..." ynh_script_progression --message="Stopping systemd service '$app'..."
ynh_systemd_action --service_name="$app" --action="stop" ynh_systemd_action --service_name="$app" --action="stop"
@ -113,36 +126,19 @@ fi
#================================================= #=================================================
# MODIFY SETTINGS # MODIFY SETTINGS
#================================================= #=================================================
ynh_script_progression --message="Modify project config file..." ynh_script_progression --message="Modify $app config file..."
# save old settings file domain=$YNH_APP_NEW_DOMAIN
settings="$final_path/settings.py" path_url=$YNH_APP_NEW_PATH
ynh_backup_if_checksum_is_different --file="$settings"
cp "../conf/settings.py" "$settings" ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
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 # GENERIC FINALISATION
#================================================= #=================================================
# START SYSTEMD SERVICE # START SYSTEMD SERVICE
#================================================= #=================================================
ynh_script_progression --message="Starting systemd services..." --weight=5 ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

View file

@ -40,7 +40,6 @@ touch "${log_file}"
ynh_script_progression --message="Storing installation settings..." ynh_script_progression --message="Storing installation settings..."
ynh_app_setting_set --app="$app" --key=admin --value="$admin" ynh_app_setting_set --app="$app" --key=admin --value="$admin"
ynh_app_setting_set --app="$app" --key=is_public --value="$is_public"
ynh_app_setting_set --app="$app" --key=public_path --value="$public_path" ynh_app_setting_set --app="$app" --key=public_path --value="$public_path"
ynh_app_setting_set --app="$app" --key=final_path --value="$final_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=log_path --value="$log_file"
@ -51,19 +50,29 @@ ynh_app_setting_set --app="$app" --key=path --value="$path_url"
# Find a free port # Find a free port
port=$(ynh_find_port --port=8000) port=$(ynh_find_port --port=8000)
# Set port as application setting # Set port as application setting
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/setting # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/setting
ynh_app_setting_set --app="$app" --key=port --value="$port" ynh_app_setting_set --app="$app" --key=port --value="$port"
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) 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) redis_db=$(ynh_redis_get_free_db)
ynh_app_setting_set --app="$app" --key=redis_db --value="$redis_db"
#-------------------------------------------------
# config_panel.toml settings:
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
#================================================= #=================================================
# STANDARD MODIFICATIONS # STANDARD MODIFICATIONS
#================================================= #=================================================
# INSTALL DEPENDENCIES # INSTALL DEPENDENCIES
#================================================= #=================================================
ynh_script_progression --message="Installing dependencies..." --weight=20 ynh_script_progression --message="Installing $app dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies" ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
@ -87,21 +96,22 @@ ynh_psql_setup_db --db_user="$db_user" --db_name="$db_name"
ynh_script_progression --message="Configuring nginx web server..." ynh_script_progression --message="Configuring nginx web server..."
# Create a dedicated nginx config # Create a dedicated nginx config
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
ynh_add_nginx_config "public_path" "port" ynh_add_nginx_config "public_path" "port"
#================================================= #=================================================
# CREATE DEDICATED USER # CREATE DEDICATED USER
#================================================= #=================================================
ynh_script_progression --message="Configuring system user..." ynh_script_progression --message="Configuring system user '$app'..."
# A home directory for venv and settings etc. # A home directory for venv and settings etc.
ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#================================================= #=================================================
# PIP INSTALLATION # PYTHON VIRTUALENV
#================================================= #=================================================
ynh_script_progression --message="Install project via pip..." --weight=50 ynh_script_progression --message="Create Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -112,64 +122,35 @@ python3 -m venv --without-pip "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset
source "${final_path}/venv/bin/activate" source "${final_path}/venv/bin/activate"
set -o nounset set -o nounset
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip 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 --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
) )
#================================================= #=================================================
# copy config files # copy config files
# ================================================ # ================================================
ynh_script_progression --message="Create project configuration files..." ynh_script_progression --message="Create $app configuration files..."
gunicorn_conf="$final_path/gunicorn.conf.py" ynh_add_config --template="gunicorn.conf.py" --destination="$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_add_config --template="manage.py" --destination="$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" chmod +x "$final_path/manage.py"
settings="$final_path/settings.py" ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
cp "../conf/settings.py" "$settings" ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
ynh_replace_string --match_string="__APP__" --replace_string="$app" --target_file="$settings" ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.py"
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"
touch "$final_path/local_settings.py" touch "$final_path/local_settings.py"
@ -187,7 +168,7 @@ cd "$final_path" || exit
./manage.py collectstatic --no-input ./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat): # Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail" ./manage.py create_superuser --username="$admin" --email="$(ynh_user_get_info "$admin" mail)"
# Check the configuration # Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later. # This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
@ -207,7 +188,7 @@ ynh_use_logrotate "$log_file"
#================================================= #=================================================
ynh_script_progression --message="Integrating 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}" yunohost service add $app --log="${log_file}"
#================================================= #=================================================
# GENERIC FINALIZATION # GENERIC FINALIZATION
@ -227,15 +208,29 @@ chmod o-rwx "$final_path"
#================================================= #=================================================
# SETUP SYSTEMD # SETUP SYSTEMD
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/systemd # https://yunohost.org/en/contribute/packaging_apps/helpers
ynh_add_systemd_config --service="$app" --template="django-for-runners.service" # https://github.com/YunoHost/yunohost/blob/dev/helpers/systemd
ynh_add_systemd_config --service="$app" --template="systemd.service"
#================================================= #=================================================
# Start for_runners via systemd # SETUP SSOWAT
#================================================= #=================================================
ynh_script_progression --message="Starting project services..." --weight=5 ynh_script_progression --message="Configuring SSOwat..."
# Make app public if necessary or protect it
if [ $is_public -eq 1 ]
then
# Everyone can access the app.
# The "main" permission is automatically created before the install script.
ynh_permission_update --permission "main" --add "visitors"
fi
#=================================================
# Start the app server via systemd
#=================================================
ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

View file

@ -36,7 +36,7 @@ fi
#================================================= #=================================================
# STOP PYINVENTORY'S SERVICES # STOP PYINVENTORY'S SERVICES
#================================================= #=================================================
ynh_script_progression --message="Stopping and removing systemd services..." --weight=5 ynh_script_progression --message="Stopping and removing systemd service '$app'..." --weight=5
ynh_remove_systemd_config --service="$app" ynh_remove_systemd_config --service="$app"

View file

@ -20,8 +20,8 @@ ynh_abort_if_errors
#================================================= #=================================================
ynh_script_progression --message="Loading 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) final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
db_name=$(ynh_app_setting_get --app="$app" --key=db_name) db_name=$(ynh_app_setting_get --app="$app" --key=db_name)
db_user=$db_name db_user=$db_name
db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd) db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
@ -34,8 +34,6 @@ path_url=$(ynh_app_setting_get --app="$app" --key=path)
#================================================= #=================================================
ynh_script_progression --message="Validating restoration parameters..." ynh_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 \ test ! -d $final_path \
|| ynh_die --message="There is already a directory: $final_path " || ynh_die --message="There is already a directory: $final_path "
@ -50,12 +48,10 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf"
#================================================= #=================================================
# RESTORE THE APP MAIN DIR # RESTORE THE APP MAIN DIR
#================================================= #=================================================
ynh_script_progression --message="Restoring the app main directory..." ynh_script_progression --message="Restoring $app main directory..."
ynh_restore_file --origin_path="$public_path"
ynh_restore_file --origin_path="$final_path" ynh_restore_file --origin_path="$final_path"
ynh_restore_file --origin_path="$public_path"
touch "$final_path/local_settings.py"
#================================================= #=================================================
# RECREATE THE DEDICATED USER # RECREATE THE DEDICATED USER
@ -83,10 +79,10 @@ ynh_script_progression --message="Reinstalling dependencies..." --weight=20
ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies" ynh_exec_warn_less ynh_install_app_dependencies "$pkg_dependencies"
#================================================= #=================================================
# REINSTALL PYTHON VIRTUALENV # PYTHON VIRTUALENV
# Maybe the backup contains a other Python version # Maybe the backup contains a other Python version
#================================================= #=================================================
ynh_script_progression --message="Upgrade Python virtualenv..." --weight=50 ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -95,19 +91,17 @@ ynh_secure_remove "${final_path}/venv"
python3 -m venv --without-pip "${final_path}/venv" python3 -m venv --without-pip "${final_path}/venv"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset
source "${final_path}/venv/bin/activate" source "${final_path}/venv/bin/activate"
set -o nounset set -o nounset
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip 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 --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
) )
@ -133,7 +127,7 @@ systemctl enable $app.service --quiet
#================================================= #=================================================
ynh_script_progression --message="Integrating service in YunoHost..." ynh_script_progression --message="Integrating service in YunoHost..."
yunohost service add $app --description="Web based management to catalog things" --log="${log_file}" yunohost service add $app --log="${log_file}"
#================================================= #=================================================
# RESTORE THE LOGROTATE CONFIGURATION # RESTORE THE LOGROTATE CONFIGURATION
@ -164,7 +158,7 @@ chmod o-rwx "$final_path"
#================================================= #=================================================
# START PYINVENTORY # START PYINVENTORY
#================================================= #=================================================
ynh_script_progression --message="Starting a systemd service..." --weight=5 ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

View file

@ -13,7 +13,6 @@ source /usr/share/yunohost/helpers
ynh_script_progression --message="Loading installation settings..." ynh_script_progression --message="Loading installation settings..."
admin=$(ynh_app_setting_get --app="$app" --key=admin) admin=$(ynh_app_setting_get --app="$app" --key=admin)
is_public=$(ynh_app_setting_get --app="$app" --key=is_public)
public_path=$(ynh_app_setting_get --app="$app" --key=public_path) public_path=$(ynh_app_setting_get --app="$app" --key=public_path)
final_path=$(ynh_app_setting_get --app="$app" --key=final_path) final_path=$(ynh_app_setting_get --app="$app" --key=final_path)
log_path=$(ynh_app_setting_get --app="$app" --key=log_path) log_path=$(ynh_app_setting_get --app="$app" --key=log_path)
@ -27,13 +26,39 @@ db_pwd=$(ynh_app_setting_get --app="$app" --key=psqlpwd)
db_name=$(ynh_sanitize_dbid --db_name="$app") db_name=$(ynh_sanitize_dbid --db_name="$app")
db_user=$db_name db_user=$db_name
admin_mail=$(ynh_user_get_info "$admin" mail)
redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db) redis_db=$(ynh_app_setting_get --app="$app" --key=redis_db)
#-------------------------------------------------
# config_panel.toml settings:
debug_enabled=$(ynh_app_setting_get --app="$app" --key=debug_enabled)
if [ -z "$debug_enabled" ]; then
debug_enabled="0"
ynh_app_setting_set --app="$app" --key=debug_enabled --value="$debug_enabled"
fi
log_level=$(ynh_app_setting_get --app="$app" --key=log_level)
if [ -z "$log_level" ]; then
log_level="WARNING"
ynh_app_setting_set --app="$app" --key=log_level --value="$log_level"
fi
admin_email=$(ynh_app_setting_get --app="$app" --key=admin_email)
if [ -z "$admin_email" ]; then
admin_email="${admin}@${domain}"
ynh_app_setting_set --app="$app" --key=admin_email --value="$admin_email"
fi
default_from_email=$(ynh_app_setting_get --app="$app" --key=default_from_email)
if [ -z "$default_from_email" ]; then
default_from_email="${app}@${domain}"
ynh_app_setting_set --app="$app" --key=default_from_email --value="$default_from_email"
fi
#================================================= #=================================================
# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP # BACKUP BEFORE UPGRADE THEN ACTIVE TRAP
#================================================= #=================================================
ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=40 ynh_script_progression --message="Backing up $app before upgrading (may take a while)..." --weight=40
# Backup the current version of the app # Backup the current version of the app
ynh_backup_before_upgrade ynh_backup_before_upgrade
@ -49,7 +74,7 @@ ynh_abort_if_errors
#================================================= #=================================================
# STOP SYSTEMD SERVICE # STOP SYSTEMD SERVICE
#================================================= #=================================================
ynh_script_progression --message="Stopping systemd services..." --weight=5 ynh_script_progression --message="Stopping systemd service '$app'..." --weight=5
ynh_systemd_action --service_name="$app" --action="stop" ynh_systemd_action --service_name="$app" --action="stop"
@ -59,7 +84,8 @@ ynh_systemd_action --service_name="$app" --action="stop"
ynh_script_progression --message="Upgrading nginx web server configuration..." ynh_script_progression --message="Upgrading nginx web server configuration..."
# Create a dedicated nginx config # Create a dedicated nginx config
# https://github.com/YunoHost/yunohost/blob/dev/data/helpers.d/nginx # https://yunohost.org/en/contribute/packaging_apps/helpers
# https://github.com/YunoHost/yunohost/blob/dev/helpers/nginx
ynh_add_nginx_config "public_path" "port" ynh_add_nginx_config "public_path" "port"
#================================================= #=================================================
@ -82,14 +108,14 @@ ynh_system_user_create --username="$app" --home_dir="$final_path" --use_shell
#================================================= #=================================================
# SETUP SYSTEMD # SETUP SYSTEMD
#================================================= #=================================================
ynh_script_progression --message="Configuring a systemd service..." ynh_script_progression --message="Configuring systemd service '$app'..." --weight=5
ynh_add_systemd_config --service="$app" --template="django-for-runners.service" ynh_add_systemd_config --service="$app" --template="systemd.service"
#================================================= #=================================================
# UPGRADE VENV # PYTHON VIRTUALENV
#================================================= #=================================================
ynh_script_progression --message="Upgrade project via pip..." --weight=50 ynh_script_progression --message="Recreate Python virtualenv..." --weight=5
# Always recreate everything fresh with current python version # Always recreate everything fresh with current python version
ynh_secure_remove "${final_path}/venv" ynh_secure_remove "${final_path}/venv"
@ -100,19 +126,17 @@ python3 -m venv --without-pip "${final_path}/venv"
cp ../conf/requirements.txt "$final_path/requirements.txt" cp ../conf/requirements.txt "$final_path/requirements.txt"
chown -R "$app:" "$final_path" chown -R "$app:" "$final_path"
#=================================================
# PIP INSTALLATION
#=================================================
ynh_script_progression --message="Install project via pip..." --weight=45
#run source in a 'sub shell' #run source in a 'sub shell'
( (
set +o nounset set +o nounset
source "${final_path}/venv/bin/activate" source "${final_path}/venv/bin/activate"
set -o nounset set -o nounset
ynh_exec_as $app $final_path/venv/bin/python3 -m ensurepip 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 --upgrade wheel pip setuptools
# for installing packages like "matplotlib"
# See: https://github.com/YunoHost-Apps/django-for-runners_ynh/issues/15
ynh_exec_as $app $final_path/venv/bin/pip install --upgrade --prefer-binary Cython
ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt" ynh_exec_as $app $final_path/venv/bin/pip3 install --no-deps -r "$final_path/requirements.txt"
) )
@ -121,52 +145,15 @@ chown -R "$app:" "$final_path"
# ================================================ # ================================================
ynh_script_progression --message="Create project configuration files..." ynh_script_progression --message="Create project configuration files..."
gunicorn_conf="$final_path/gunicorn.conf.py" ynh_add_config --template="gunicorn.conf.py" --destination="$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_add_config --template="manage.py" --destination="$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" chmod +x "$final_path/manage.py"
# save old settings file ynh_add_config --template="settings.py" --destination="$final_path/settings.py"
settings="$final_path/settings.py" ynh_add_config --template="setup_user.py" --destination="$final_path/setup_user.py"
ynh_backup_if_checksum_is_different --file="$settings" ynh_add_config --template="urls.py" --destination="$final_path/urls.py"
ynh_add_config --template="wsgi.py" --destination="$final_path/wsgi.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"
# Recalculate and store the config file checksum into the app settings
ynh_store_file_checksum --file="$settings"
ynh_backup_if_checksum_is_different --file="$final_path/setup_user.py"
cp ../conf/setup_user.py "$final_path/setup_user.py"
ynh_backup_if_checksum_is_different --file="$final_path/urls.py"
cp ../conf/urls.py "$final_path/urls.py"
ynh_backup_if_checksum_is_different --file="$final_path/wsgi.py"
cp ../conf/wsgi.py "$final_path/wsgi.py"
touch "$final_path/local_settings.py"
#================================================= #=================================================
# MIGRATE PYINVENTORY # MIGRATE PYINVENTORY
@ -182,7 +169,7 @@ cd "$final_path" || exit
./manage.py collectstatic --no-input ./manage.py collectstatic --no-input
# Create/update Django superuser (set unusable password, because auth done via SSOwat): # Create/update Django superuser (set unusable password, because auth done via SSOwat):
./manage.py create_superuser --username="$admin" --email="$admin_mail" ./manage.py create_superuser --username="$admin" --email="$(ynh_user_get_info "$admin" mail)"
# Check the configuration # Check the configuration
# This may fail in some cases with errors, etc., but the app works and the user can fix issues later. # This may fail in some cases with errors, etc., but the app works and the user can fix issues later.
@ -202,7 +189,7 @@ ynh_use_logrotate --non-append
#================================================= #=================================================
ynh_script_progression --message="Integrating 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}" yunohost service add $app --log="${log_file}"
#================================================= #=================================================
# GENERIC FINALIZATION # GENERIC FINALIZATION
@ -220,9 +207,9 @@ chmod o-rwx "$public_path"
chmod o-rwx "$final_path" chmod o-rwx "$final_path"
#================================================= #=================================================
# Start for_runners via systemd # Start the app server via systemd
#================================================= #=================================================
ynh_script_progression --message="Starting project services..." --weight=5 ynh_script_progression --message="Starting systemd service '$app'..." --weight=5
ynh_systemd_action --service_name="$app" --action="start" ynh_systemd_action --service_name="$app" --action="start"

43
tests/conftest.py Normal file
View file

@ -0,0 +1,43 @@
"""
Special pytest init:
- Build a "local_test" YunoHost installation
- init Django with this local test installation
So the pytests will run against this local test installation
"""
import os
import sys
from pathlib import Path
import django
from django_yunohost_integration.local_test import create_local_test
BASE_PATH = Path(__file__).parent.parent
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
def pytest_configure():
print('Compile YunoHost files...')
final_path = create_local_test(
django_settings_path=BASE_PATH / 'conf' / 'settings.py',
destination=BASE_PATH / 'local_test',
runserver=False,
extra_replacements={
'__DEBUG_ENABLED__': '0',
'__LOG_LEVEL__': 'INFO',
'__ADMIN_EMAIL__': 'foo-bar@test.tld',
'__DEFAULT_FROM_EMAIL__': 'django_app@test.tld',
},
)
print('Local test files created here:')
print(f'"{final_path}"')
os.chdir(final_path)
final_home_str = str(final_path)
if final_home_str not in sys.path:
sys.path.insert(0, final_home_str)
django.setup()

View file

@ -23,12 +23,19 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
def test_settings(self): def test_settings(self):
assert settings.PATH_URL == 'app_path' assert settings.PATH_URL == 'app_path'
assert str(settings.FINAL_HOME_PATH).endswith('/local_test/opt_yunohost') assert str(settings.FINALPATH).endswith('/local_test/opt_yunohost')
assert str(settings.FINAL_WWW_PATH).endswith('/local_test/var_www') assert str(settings.PUBLIC_PATH).endswith('/local_test/var_www')
assert str(settings.LOG_FILE).endswith('/local_test/var_log_django-for-runners.log') assert str(settings.LOG_FILE).endswith('/local_test/var_log_django-for-runners.log')
assert settings.ROOT_URLCONF == 'urls' assert settings.ROOT_URLCONF == 'urls'
def test_config_panel_settings(self):
# config_panel.toml settings, set via tests.conftest.pytest_configure():
assert settings.DEBUG_ENABLED == '0' and settings.DEBUG is False
assert settings.LOG_LEVEL == 'INFO'
assert settings.ADMIN_EMAIL == 'foo-bar@test.tld'
assert settings.DEFAULT_FROM_EMAIL == 'django_app@test.tld'
def test_urls(self): def test_urls(self):
assert reverse('admin:index') == '/app_path/' assert reverse('admin:index') == '/app_path/'
@ -44,6 +51,10 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
# ) == ('/app_path/media/token/foo/bar/') # ) == ('/app_path/media/token/foo/bar/')
def test_auth(self): def test_auth(self):
assert settings.PATH_URL == 'app_path'
url = reverse('admin:index')
assert url == '/app_path/'
# SecurityMiddleware should redirects all non-HTTPS requests to HTTPS: # SecurityMiddleware should redirects all non-HTTPS requests to HTTPS:
assert settings.SECURE_SSL_REDIRECT is True assert settings.SECURE_SSL_REDIRECT is True
response = self.client.get('/app_path/', secure=False) response = self.client.get('/app_path/', secure=False)
@ -59,7 +70,6 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
response, expected_url='/app_path/login/?next=/app_path/', fetch_redirect_response=False response, expected_url='/app_path/login/?next=/app_path/', fetch_redirect_response=False
) )
@override_settings(SECURE_SSL_REDIRECT=False)
def test_create_unknown_user(self): def test_create_unknown_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
@ -70,16 +80,16 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
HTTP_REMOTE_USER='test', HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='test', HTTP_AUTH_USER='test',
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
secure=True,
) )
assert User.objects.count() == 1 assert User.objects.count() == 1
user = User.objects.first() user = User.objects.first()
assert user.username == 'test' assert user.username == 'test'
assert user.is_active is True assert user.is_active is True
assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler assert user.is_staff is True # Set by: conf.setup_user.setup_project_user
assert user.is_superuser is False assert user.is_superuser is False
assert response.status_code == 200
self.assert_html_parts( self.assert_html_parts(
response, response,
parts=( parts=(
@ -88,7 +98,6 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
), ),
) )
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_auth_user(self): def test_wrong_auth_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
assert AccessLog.objects.count() == 0 assert AccessLog.objects.count() == 0
@ -100,20 +109,20 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
HTTP_REMOTE_USER='test', HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='foobar', # <<< wrong user name HTTP_AUTH_USER='foobar', # <<< wrong user name
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
secure=True,
) )
assert User.objects.count() == 1 assert User.objects.count() == 1
user = User.objects.first() user = User.objects.first()
assert user.username == 'test' assert user.username == 'test'
assert user.is_active is True assert user.is_active is True
assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler assert user.is_staff is True # Set by: conf.setup_user.setup_project_user
assert user.is_superuser is False assert user.is_superuser is False
assert AccessLog.objects.count() == 1 assert AccessLog.objects.count() == 1
assert response.status_code == 403 # Forbidden assert response.status_code == 403 # Forbidden
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_cookie(self): def test_wrong_cookie(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
assert AccessLog.objects.count() == 0 assert AccessLog.objects.count() == 0
@ -125,20 +134,20 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
HTTP_REMOTE_USER='test', HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='test', HTTP_AUTH_USER='test',
HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz', HTTP_AUTHORIZATION='basic dGVzdDp0ZXN0MTIz',
secure=True,
) )
assert User.objects.count() == 1 assert User.objects.count() == 1
user = User.objects.first() user = User.objects.first()
assert user.username == 'test' assert user.username == 'test'
assert user.is_active is True assert user.is_active is True
assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler assert user.is_staff is True # Set by: conf.setup_user.setup_project_user
assert user.is_superuser is False assert user.is_superuser is False
assert AccessLog.objects.count() == 1 assert AccessLog.objects.count() == 1
assert response.status_code == 403 # Forbidden assert response.status_code == 403 # Forbidden
@override_settings(SECURE_SSL_REDIRECT=False)
def test_wrong_authorization_user(self): def test_wrong_authorization_user(self):
assert User.objects.count() == 0 assert User.objects.count() == 0
@ -149,15 +158,17 @@ class DjangoYnhTestCase(HtmlAssertionMixin, TestCase):
HTTP_REMOTE_USER='test', HTTP_REMOTE_USER='test',
HTTP_AUTH_USER='test', HTTP_AUTH_USER='test',
HTTP_AUTHORIZATION=generate_basic_auth( HTTP_AUTHORIZATION=generate_basic_auth(
username='foobar', password='test123' username='foobar', # <<< wrong user name
), # <<< wrong user name password='test123',
),
secure=True,
) )
assert User.objects.count() == 1 assert User.objects.count() == 1
user = User.objects.first() user = User.objects.first()
assert user.username == 'test' assert user.username == 'test'
assert user.is_active is True assert user.is_active is True
assert user.is_staff is True # Set by: conf.django_ynh_demo_urls.setup_user_handler assert user.is_staff is True # Set by: conf.setup_user.setup_project_user
assert user.is_superuser is False assert user.is_superuser is False
assert AccessLog.objects.count() == 1 assert AccessLog.objects.count() == 1

View file

@ -4,8 +4,10 @@ import shutil
import subprocess import subprocess
from pathlib import Path from pathlib import Path
import tomli
from bx_django_utils.filename import clean_filename from bx_django_utils.filename import clean_filename
from bx_py_utils.path import assert_is_dir, assert_is_file from bx_py_utils.path import assert_is_dir, assert_is_file
from django_tools.unittest_utils.project_setup import check_editor_config
import for_runners import for_runners
@ -22,13 +24,20 @@ def assert_file_contains_string(file_path, string):
def test_version(): def test_version():
version = for_runners.__version__ upstream_version = for_runners.__version__
pyproject_toml_path = Path(PACKAGE_ROOT, 'pyproject.toml')
pyproject_toml = tomli.loads(pyproject_toml_path.read_text(encoding='UTF-8'))
pyproject_version = pyproject_toml['tool']['poetry']['version']
assert pyproject_version.startswith(f'{upstream_version}+ynh')
# pyproject.toml needs a PEP 440 conform version and used "+ynh"
# the YunoHost syntax is: "~ynh", just "convert this:
manifest_version = pyproject_version.replace('+', '~')
assert_file_contains_string( assert_file_contains_string(
file_path=Path(PACKAGE_ROOT, 'pyproject.toml'), string=f'version = "{version}~ynh' file_path=Path(PACKAGE_ROOT, 'manifest.json'),
) string=f'"version": "{manifest_version}"',
assert_file_contains_string(
file_path=Path(PACKAGE_ROOT, 'manifest.json'), string=f'"version": "{version}~ynh'
) )
@ -52,7 +61,7 @@ def test_poetry_check():
def test_requirements_txt(): def test_requirements_txt():
requirements_txt = Path('conf', 'requirements.txt') requirements_txt = PACKAGE_ROOT / 'conf' / 'requirements.txt'
assert_is_file(requirements_txt) assert_is_file(requirements_txt)
output = poetry_check_output('export', '-f', 'requirements.txt') output = poetry_check_output('export', '-f', 'requirements.txt')
@ -81,9 +90,15 @@ def test_screenshot_filenames():
renamed = [] renamed = []
for file_path in screenshot_path.iterdir(): for file_path in screenshot_path.iterdir():
file_name = file_path.name file_name = file_path.name
if file_name.startswith('.'):
continue
cleaned_name = clean_filename(file_name) cleaned_name = clean_filename(file_name)
if cleaned_name != file_name: if cleaned_name != file_name:
new_path = file_path.with_name(cleaned_name) new_path = file_path.with_name(cleaned_name)
file_path.rename(new_path) file_path.rename(new_path)
renamed.append(f'{file_name!r} renamed to {cleaned_name!r}') renamed.append(f'{file_name!r} renamed to {cleaned_name!r}')
assert not renamed, f'Bad screenshots file names found: {", ".join(renamed)}' assert not renamed, f'Bad screenshots file names found: {", ".join(renamed)}'
def test_check_editor_config():
check_editor_config(package_root=PACKAGE_ROOT)