""" Django settings for breccia_mapper project. Generated by 'django-admin startproject' using Django 2.2.9. For more information on this file, see https://docs.djangoproject.com/en/2.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/2.2/ref/settings/ Before production deployment, see https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ Many configuration settings are input from `settings.ini`. The most likely required settings are: SECRET_KEY, DEBUG, ALLOWED_HOSTS, DATABASE_URL, PROJECT_*_NAME, EMAIL_* - PARENT_PROJECT_NAME default: Parent Project Name Displayed in templates where the name of the parent project should be used - PROJECT_LONG_NAME default: Project Long Name Displayed in templates where the full name of the project should be used - PROJECT_SHORT_NAME default: shortname Displayed in templates where a short identifier for the project should be used - SECRET_KEY (REQUIRED) Used to generate CSRF tokens - must never be made public - DEBUG default: False Should the server run in debug mode? Provides information to users which is unsafe in production - ALLOWED_HOSTS default: * if DEBUG else localhost Accepted values for server header in request - protects against CSRF and CSS attacks - DATABASE_URL default: sqlite://db.sqlite3 URL to database - uses format described at https://github.com/jacobian/dj-database-url - DBBACKUP_STORAGE_LOCATION default: .dbbackup Directory where database backups should be stored - LANGUAGE_CODE default: en-gb Default language - used for translation - has not been enabled - TIME_ZONE default: UTC Default timezone - LOG_LEVEL default: INFO Level of messages written to log file - LOG_FILENAME default: debug.log Path to logfile - LOG_DAYS default: 14 Number of days of logs to keep - logfile is rotated out at the end of each day - EMAIL_HOST default: None Hostname of SMTP server - DEFAULT_FROM_EMAIL default: None Email address from which messages are sent - EMAIL_FILE_PATH (debug only) default: mail.log Directory where emails will be stored if not using an SMTP server - EMAIL_HOST_USER default: None Username to authenticate with SMTP server - EMAIL_HOST_PASSWORD default: None Password to authenticate with SMTP server - EMAIL_PORT default: 25 Port to access on SMTP server - EMAIL_USE_TLS default: True if EMAIL_PORT == 587 else False Use TLS to communicate with SMTP server? Usually on port 587 - EMAIL_USE_SSL default: True if EMAIL_PORT == 465 else False Use SSL to communicate with SMTP server? Usually on port 465 - GOOGLE_MAPS_API_KEY default: None Google Maps API key to display maps of people's locations """ import collections import logging import logging.config import pathlib from django.urls import reverse_lazy from decouple import config, Csv import dj_database_url # Settings exported to templates # https://github.com/jakubroztocil/django-settings-export SETTINGS_EXPORT = [ 'DEBUG', 'PARENT_PROJECT_NAME', 'PROJECT_LONG_NAME', 'PROJECT_SHORT_NAME', 'GOOGLE_MAPS_API_KEY', ] PARENT_PROJECT_NAME = config('PARENT_PROJECT_NAME', default='Parent Project Name') PROJECT_LONG_NAME = config('PROJECT_LONG_NAME', default='Project Long Name') PROJECT_SHORT_NAME = config('PROJECT_SHORT_NAME', default='shortname') # Build paths inside the project like this: BASE_DIR.joinpath(...) BASE_DIR = pathlib.Path(__file__).parent.parent # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = config('SECRET_KEY') # SECURITY WARNING: don't run with debug turned on in production! DEBUG = config('DEBUG', default=False, cast=bool) ALLOWED_HOSTS = config( 'ALLOWED_HOSTS', default='*' if DEBUG else '127.0.0.1,localhost,localhost.localdomain', cast=Csv()) # Application definition DJANGO_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] THIRD_PARTY_APPS = [ 'bootstrap4', 'constance', 'constance.backends.database', 'dbbackup', 'django_countries', 'django_select2', 'rest_framework', 'post_office', 'bootstrap_datepicker_plus', 'hijack', 'compat', ] FIRST_PARTY_APPS = [ 'people', 'activities', 'export', ] INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + FIRST_PARTY_APPS MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'breccia_mapper.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR.joinpath('breccia_mapper', 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django_settings_export.settings_export', 'constance.context_processors.config', 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'breccia_mapper.wsgi.application' # Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases DATABASES = { 'default': config('DATABASE_URL', default='sqlite:///' + str(BASE_DIR.joinpath('db.sqlite3')), cast=dj_database_url.parse) } # Django DBBackup # https://django-dbbackup.readthedocs.io/en/stable/index.html DBBACKUP_STORAGE = 'django.core.files.storage.FileSystemStorage' DBBACKUP_STORAGE_OPTIONS = { 'location': config('DBBACKUP_STORAGE_LOCATION', default=BASE_DIR.joinpath('.dbbackup')), } # Django REST Framework # https://www.django-rest-framework.org/ REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework_csv.renderers.CSVRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ], } # Password validation # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Custom user model # https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project AUTH_USER_MODEL = 'people.User' # Login flow LOGIN_URL = reverse_lazy('login') LOGIN_REDIRECT_URL = reverse_lazy('people:person.profile') # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ LANGUAGE_CODE = config('LANGUAGE_CODE', default='en-gb') TIME_ZONE = config('TIME_ZONE', default='UTC') USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR.joinpath('static') STATICFILES_DIRS = [BASE_DIR.joinpath('breccia_mapper', 'static')] # Logging - NB the logger name is empty to capture all output LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'level': config('LOG_LEVEL', default='INFO'), 'class': 'logging.handlers.TimedRotatingFileHandler', 'filename': config('LOG_FILENAME', default='debug.log'), 'when': 'midnight', 'backupCount': config('LOG_DAYS', default=14, cast=int), 'formatter': 'timestamped', }, 'console': { 'level': config('LOG_LEVEL', default='INFO'), 'class': 'logging.StreamHandler', 'formatter': 'timestamped', }, }, 'loggers': { '': { 'handlers': ['console', 'file'], 'level': config('LOG_LEVEL', default='INFO'), 'propagate': True, }, }, 'formatters': { 'timestamped': { 'format': '[{asctime} {levelname} {module} {funcName}] {message}', 'style': '{', } } } # Initialise logger now so we can use it in this file LOGGING_CONFIG = None logging.config.dictConfig(LOGGING) logger = logging.getLogger(__name__) # pylint: disable=invalid-name # Admin panel variables CONSTANCE_CONFIG = { 'NOTICE_TEXT': ( '', 'Text to be displayed in a notice banner at the top of every page.'), 'NOTICE_CLASS': ( 'alert-warning', 'CSS class to use for background of notice banner.'), 'CONSENT_TEXT': ( 'This is template consent text and should have been replaced. Please contact an admin.', 'Text to be displayed to ask for consent for data collection.'), 'PERSON_LIST_HELP': ( '', 'Help text to display at the top of the people list.'), 'ORGANISATION_LIST_HELP': ( '', 'Help text to display at the top of the organisaton list.'), } # yapf: disable CONSTANCE_CONFIG_FIELDSETS = { 'Notice Banner': ( 'NOTICE_TEXT', 'NOTICE_CLASS', ), 'Data Collection': ('CONSENT_TEXT', ), 'Help Text': ('PERSON_LIST_HELP', 'ORGANISATION_LIST_HELP'), } CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' # Django Hijack settings # See https://django-hijack.readthedocs.io/en/stable/ HIJACK_USE_BOOTSTRAP = True # Bootstrap settings # See https://django-bootstrap4.readthedocs.io/en/latest/settings.html BOOTSTRAP4 = { 'include_jquery': 'full', } # Email backend settings # See https://docs.djangoproject.com/en/3.0/topics/email EMAIL_HOST = config('EMAIL_HOST', default=None) DEFAULT_FROM_EMAIL = config( 'DEFAULT_FROM_EMAIL', default=f'{PROJECT_SHORT_NAME}@localhost.localdomain') SERVER_EMAIL = DEFAULT_FROM_EMAIL if EMAIL_HOST is None: EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' EMAIL_FILE_PATH = config('EMAIL_FILE_PATH', default=str(BASE_DIR.joinpath('mail.log'))) else: EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST_USER = config('EMAIL_HOST_USER', default=None) EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default=None) EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int) EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=(EMAIL_PORT == 587), cast=bool) EMAIL_USE_SSL = config('EMAIL_USE_SSL', default=(EMAIL_PORT == 465), cast=bool) # Upstream API keys GOOGLE_MAPS_API_KEY = config('GOOGLE_MAPS_API_KEY', default=None) # Import customisation app settings if present try: from custom.settings import ( CUSTOMISATION_NAME, TEMPLATE_NAME_INDEX, TEMPLATE_WELCOME_EMAIL_NAME, CONSTANCE_CONFIG as constance_config_custom, CONSTANCE_CONFIG_FIELDSETS as constance_config_fieldsets_custom ) # yapf: disable CONSTANCE_CONFIG.update(constance_config_custom) CONSTANCE_CONFIG_FIELDSETS.update(constance_config_fieldsets_custom) INSTALLED_APPS.append('custom') logger.info("Loaded customisation app: %s", CUSTOMISATION_NAME) except ImportError as exc: logger.info("No customisation app loaded: %s", exc) # Set default values if no customisations loaded CUSTOMISATION_NAME = None TEMPLATE_NAME_INDEX = 'index.html' TEMPLATE_WELCOME_EMAIL_NAME = 'welcome-email'