kopia lustrzana https://github.com/jedie/PyInventory
382 wiersze
12 KiB
Python
382 wiersze
12 KiB
Python
'''
|
|
Base Django settings
|
|
'''
|
|
|
|
import logging
|
|
from pathlib import Path as __Path
|
|
|
|
from ckeditor.configs import DEFAULT_CONFIG
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
|
###############################################################################
|
|
|
|
# Build paths relative to the project root:
|
|
PROJECT_PATH = __Path(__file__).parent.parent.parent
|
|
print(f'PROJECT_PATH:{PROJECT_PATH}')
|
|
|
|
if __Path('/.dockerenv').is_file():
|
|
# We are inside a docker container
|
|
BASE_PATH = __Path('/django_volumes')
|
|
assert BASE_PATH.is_dir()
|
|
else:
|
|
# Build paths relative to the current working directory:
|
|
BASE_PATH = __Path().cwd().resolve()
|
|
|
|
print(f'BASE_PATH:{BASE_PATH}')
|
|
|
|
# Paths with Django dev. server:
|
|
# BASE_PATH...: .../django-for-runners
|
|
# PROJECT_PATH: .../django-for-runners/src
|
|
#
|
|
# Paths in Docker container:
|
|
# BASE_PATH...: /for_runners_volumes
|
|
# PROJECT_PATH: /usr/local/lib/python3.9/site-packages
|
|
|
|
###############################################################################
|
|
|
|
|
|
# SECURITY WARNING: don't run with debug turned on in production!
|
|
DEBUG = False
|
|
|
|
# Serve static/media files by Django?
|
|
# In production Caddy should serve this!
|
|
SERVE_FILES = False
|
|
|
|
|
|
# SECURITY WARNING: keep the secret key used in production secret!
|
|
__SECRET_FILE = __Path(BASE_PATH, 'secret.txt').resolve()
|
|
if not __SECRET_FILE.is_file():
|
|
print(f'Generate {__SECRET_FILE}')
|
|
from secrets import token_urlsafe as __token_urlsafe
|
|
__SECRET_FILE.open('w').write(__token_urlsafe(128))
|
|
|
|
SECRET_KEY = __SECRET_FILE.open('r').read().strip()
|
|
|
|
|
|
# Application definition
|
|
|
|
INSTALLED_APPS = [
|
|
'django.contrib.admin',
|
|
'django.contrib.auth',
|
|
'django.contrib.contenttypes',
|
|
'django.contrib.sessions',
|
|
'django.contrib.messages',
|
|
'django.contrib.staticfiles',
|
|
'django.contrib.sites',
|
|
|
|
'bx_django_utils', # https://github.com/boxine/bx_django_utils
|
|
'import_export', # https://github.com/django-import-export/django-import-export
|
|
'dbbackup', # https://github.com/django-dbbackup/django-dbbackup
|
|
'ckeditor', # https://github.com/django-ckeditor/django-ckeditor
|
|
'ckeditor_uploader', # https://github.com/django-ckeditor/django-ckeditor
|
|
'reversion', # https://github.com/etianen/django-reversion
|
|
'reversion_compare', # https://github.com/jedie/django-reversion-compare
|
|
'tagulous', # https://github.com/radiac/django-tagulous
|
|
'adminsortable2', # https://github.com/jrief/django-admin-sortable2
|
|
'axes', # https://github.com/jazzband/django-axes
|
|
'django_processinfo', # https://github.com/jedie/django-processinfo/
|
|
|
|
# https://github.com/jedie/django-tools/tree/master/django_tools/serve_media_app
|
|
'django_tools.serve_media_app.apps.UserMediaFilesConfig',
|
|
|
|
# https://github.com/jedie/django-tools/tree/master/django_tools/model_version_protect
|
|
'django_tools.model_version_protect.apps.ModelVersionProtectConfig',
|
|
|
|
'inventory.apps.InventoryConfig',
|
|
]
|
|
|
|
ROOT_URLCONF = 'inventory_project.urls'
|
|
WSGI_APPLICATION = 'inventory_project.wsgi.application'
|
|
SITE_ID = 1
|
|
|
|
AUTHENTICATION_BACKENDS = [
|
|
'axes.backends.AxesBackend',
|
|
'django.contrib.auth.backends.ModelBackend',
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
'django_processinfo.middlewares.ProcessInfoMiddleware',
|
|
|
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
'django.middleware.locale.LocaleMiddleware',
|
|
'django.middleware.common.CommonMiddleware',
|
|
'django.middleware.csrf.CsrfViewMiddleware',
|
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
|
|
'inventory.middlewares.RequestDictMiddleware',
|
|
|
|
'django.contrib.messages.middleware.MessageMiddleware',
|
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
|
'django.middleware.security.SecurityMiddleware',
|
|
|
|
'axes.middleware.AxesMiddleware', # AxesMiddleware should be the last middleware
|
|
]
|
|
|
|
TEMPLATES = [
|
|
{
|
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
|
'DIRS': [str(__Path(PROJECT_PATH, 'inventory_project', 'templates'))],
|
|
'APP_DIRS': True,
|
|
'OPTIONS': {
|
|
'context_processors': [
|
|
'django.template.context_processors.debug',
|
|
'django.template.context_processors.request',
|
|
'django.contrib.auth.context_processors.auth',
|
|
'django.contrib.messages.context_processors.messages',
|
|
'inventory.context_processors.inventory_version_string',
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
# _____________________________________________________________________________
|
|
# Internationalization
|
|
|
|
LANGUAGE_CODE = 'en'
|
|
|
|
LANGUAGES = [
|
|
('ca', _('Catalan')),
|
|
('de', _('German')),
|
|
('en', _('English')),
|
|
('es', _('Spanish'))
|
|
]
|
|
USE_I18N = True
|
|
USE_L10N = True
|
|
TIME_ZONE = 'Europe/Paris'
|
|
USE_TZ = True
|
|
|
|
# _____________________________________________________________________________
|
|
# Static files (CSS, JavaScript, Images)
|
|
|
|
STATIC_URL = '/static/'
|
|
STATIC_ROOT = str(__Path(BASE_PATH, 'static'))
|
|
|
|
MEDIA_URL = '/media/'
|
|
MEDIA_ROOT = str(__Path(BASE_PATH, 'media'))
|
|
|
|
# _____________________________________________________________________________
|
|
# django-processinfo
|
|
|
|
from django_processinfo import app_settings as PROCESSINFO # noqa
|
|
|
|
|
|
PROCESSINFO.ADD_INFO = False # Don't add info in HTML page
|
|
|
|
# _____________________________________________________________________________
|
|
# Django-dbbackup
|
|
|
|
DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
|
DBBACKUP_STORAGE_OPTIONS = {'location': str(__Path(BASE_PATH, 'backups'))}
|
|
|
|
# _____________________________________________________________________________
|
|
# django-ckeditor
|
|
|
|
CKEDITOR_BASEPATH = STATIC_URL + 'ckeditor/ckeditor/'
|
|
CKEDITOR_FILENAME_GENERATOR = 'inventory.ckeditor_upload.get_filename'
|
|
CKEDITOR_DEFAULT_CONFIG = DEFAULT_CONFIG
|
|
CKEDITOR_DEFAULT_CONFIG.update({
|
|
'removeButtons': 'Language,Cut,Copy,Paste,Undo,Redo,Anchor',
|
|
|
|
# plugins are here: .../site-packages/ckeditor/static/ckeditor/ckeditor/plugins
|
|
# and here: https://github.com/ckeditor/ckeditor4/tree/major/plugins
|
|
# See also: .../site-packages/ckeditor/static/ckeditor/ckeditor/build-config.js
|
|
'removePlugins': (
|
|
# Generated with devshell command:
|
|
# (inventory) ckeditor_info
|
|
'a11yhelp',
|
|
# 'about',
|
|
'adobeair',
|
|
'ajax',
|
|
'autoembed',
|
|
# 'autogrow',
|
|
'autolink',
|
|
# 'basicstyles',
|
|
'bbcode',
|
|
'bidi',
|
|
# 'blockquote',
|
|
'clipboard',
|
|
'codesnippet',
|
|
'codesnippetgeshi',
|
|
# 'colorbutton',
|
|
# 'colordialog',
|
|
'contextmenu',
|
|
'copyformatting',
|
|
'devtools',
|
|
'dialog',
|
|
'dialogadvtab',
|
|
'div',
|
|
'divarea',
|
|
'docprops',
|
|
# 'elementspath',
|
|
'embed',
|
|
'embedbase',
|
|
'embedsemantic',
|
|
'enterkey',
|
|
# 'entities',
|
|
'exportpdf',
|
|
# 'filebrowser',
|
|
# 'filetools',
|
|
'find',
|
|
'flash',
|
|
# 'floatingspace',
|
|
# 'font',
|
|
# 'format',
|
|
'forms',
|
|
# 'horizontalrule',
|
|
'htmlwriter',
|
|
'iframe',
|
|
'iframedialog',
|
|
# 'image',
|
|
# 'image2',
|
|
# 'indentblock',
|
|
# 'indentlist',
|
|
# 'justify',
|
|
'language',
|
|
# 'lineutils',
|
|
# 'link',
|
|
# 'list',
|
|
# 'liststyle',
|
|
'magicline',
|
|
'mathjax',
|
|
# 'maximize',
|
|
# 'menubutton',
|
|
'newpage',
|
|
'notification',
|
|
'notificationaggregator',
|
|
'pagebreak',
|
|
'pastefromgdocs',
|
|
'pastefromword',
|
|
'pastetext',
|
|
'pastetools',
|
|
'placeholder',
|
|
'preview',
|
|
'print',
|
|
# 'removeformat',
|
|
# 'resize',
|
|
'save',
|
|
'scayt',
|
|
'selectall',
|
|
'sharedspace',
|
|
# 'showblocks',
|
|
# 'showborders',
|
|
'smiley',
|
|
# 'sourcearea',
|
|
'sourcedialog',
|
|
'specialchar',
|
|
'stylescombo',
|
|
'stylesheetparser',
|
|
'tab',
|
|
# 'table',
|
|
# 'tableresize',
|
|
# 'tableselection',
|
|
# 'tabletools',
|
|
'templates',
|
|
# 'toolbar',
|
|
'uicolor',
|
|
# 'undo',
|
|
# 'uploadimage',
|
|
# 'uploadwidget',
|
|
'widget',
|
|
'wsc',
|
|
# 'wysiwygarea',
|
|
'xml',
|
|
),
|
|
'toolbar_PyInventoryToolbarConfig': [
|
|
{'name': 'basicstyles', 'items': [
|
|
'Bold', 'Italic', 'Underline', 'Strike',
|
|
'-',
|
|
'RemoveFormat'
|
|
]},
|
|
{'name': 'paragraph', 'items': [
|
|
'NumberedList', 'BulletedList',
|
|
'-',
|
|
'Outdent', 'Indent',
|
|
'-',
|
|
'Blockquote',
|
|
'-',
|
|
'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock',
|
|
]},
|
|
{'name': 'links', 'items': ['Link', 'Unlink', 'Anchor']},
|
|
{'name': 'insert', 'items': ['Image', 'Table', 'HorizontalRule']},
|
|
'/',
|
|
{'name': 'styles', 'items': ['Styles', 'Format', 'Font', 'FontSize']},
|
|
{'name': 'colors', 'items': ['TextColor', 'BGColor']},
|
|
{'name': 'tools', 'items': ['Maximize', 'ShowBlocks', 'Source']},
|
|
{'name': 'about', 'items': ['About']},
|
|
],
|
|
'toolbar': 'PyInventoryToolbarConfig',
|
|
'height': '25em',
|
|
'width': '100%',
|
|
})
|
|
CKEDITOR_CONFIGS = {
|
|
'ItemModel.description': CKEDITOR_DEFAULT_CONFIG,
|
|
'LocationModel.description': CKEDITOR_DEFAULT_CONFIG,
|
|
'MemoModel.description': CKEDITOR_DEFAULT_CONFIG,
|
|
}
|
|
CKEDITOR_RESTRICT_BY_USER = True
|
|
CKEDITOR_RESTRICT_BY_DATE = True
|
|
CKEDITOR_UPLOAD_PATH = 'uploads/'
|
|
CKEDITOR_IMAGE_BACKEND = 'pillow'
|
|
CKEDITOR_THUMBNAIL_SIZE = (300, 300)
|
|
CKEDITOR_IMAGE_QUALITY = 40
|
|
CKEDITOR_BROWSE_SHOW_DIRS = True
|
|
CKEDITOR_ALLOW_NONIMAGE_FILES = True
|
|
|
|
# _____________________________________________________________________________
|
|
# http://radiac.net/projects/django-tagulous/documentation/installation/#settings
|
|
|
|
TAGULOUS_NAME_MAX_LENGTH = 255
|
|
TAGULOUS_SLUG_MAX_LENGTH = 50
|
|
TAGULOUS_LABEL_MAX_LENGTH = TAGULOUS_NAME_MAX_LENGTH
|
|
TAGULOUS_SLUG_TRUNCATE_UNIQUE = 5
|
|
TAGULOUS_SLUG_ALLOW_UNICODE = False
|
|
|
|
SERIALIZATION_MODULES = {
|
|
'xml': 'tagulous.serializers.xml_serializer',
|
|
'json': 'tagulous.serializers.json',
|
|
'python': 'tagulous.serializers.python',
|
|
'yaml': 'tagulous.serializers.pyyaml',
|
|
}
|
|
|
|
# _____________________________________________________________________________
|
|
# cut 'pathname' in log output
|
|
|
|
old_factory = logging.getLogRecordFactory()
|
|
|
|
|
|
def cut_path(pathname, max_length):
|
|
if len(pathname) <= max_length:
|
|
return pathname
|
|
return f'...{pathname[-(max_length - 3):]}'
|
|
|
|
|
|
def record_factory(*args, **kwargs):
|
|
record = old_factory(*args, **kwargs)
|
|
record.cut_path = cut_path(record.pathname, 30)
|
|
return record
|
|
|
|
|
|
logging.setLogRecordFactory(record_factory)
|
|
|
|
# -----------------------------------------------------------------------------
|
|
|
|
LOGGING = {
|
|
'version': 1,
|
|
'disable_existing_loggers': True,
|
|
'formatters': {
|
|
'colored': { # https://github.com/borntyping/python-colorlog
|
|
'()': 'colorlog.ColoredFormatter',
|
|
'format': '%(log_color)s%(asctime)s %(levelname)8s %(cut_path)s:%(lineno)-3s %(message)s',
|
|
}
|
|
},
|
|
'handlers': {'console': {'class': 'colorlog.StreamHandler', 'formatter': 'colored'}},
|
|
'loggers': {
|
|
'': {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False},
|
|
'django': {'handlers': ['console'], 'level': 'INFO', 'propagate': False},
|
|
'axes': {'handlers': ['console'], 'level': 'WARNING', 'propagate': False},
|
|
'django_tools': {'handlers': ['console'], 'level': 'INFO', 'propagate': False},
|
|
'inventory': {'handlers': ['console'], 'level': 'DEBUG', 'propagate': False},
|
|
},
|
|
}
|