Files
vontor-cz/vontor_cz/settings.py

391 lines
12 KiB
Python

"""
Django settings for vontor_cz project.
Generated by 'django-admin startproject' using Django 5.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""
import os
from pathlib import Path
from django.core.management.utils import get_random_secret_key
from django.conf import settings
from django.db import OperationalError, connections
from dotenv import load_dotenv
load_dotenv() # Pouze načte proměnné lokálně, pokud nejsou dostupné
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "kokotiJsouKokoticozserovna2kokote")
# SECURITY WARNING: don't run with debug turned on in production!
if os.getenv("DEBUG", "").lower() in ["true", "1", "yes"]:
DEBUG = True
else:
DEBUG = False
if os.getenv("SSL", "").lower() in ["true", "1", "yes"]:
SSL = True
else:
SSL = False
print(f"DEBUG state: {str(DEBUG)}\nDEBUG .env raw: {os.getenv("DEBUG", "")}")
print(f"SSL state: {str(SSL)}\SSL .env raw: {os.getenv("SSL", "")}")
ALLOWED_HOSTS = ["www.vontor.cz", "vontor.cz", "https://peerjs.vontor.cz"]
CSRF_TRUSTED_ORIGINS = ['https://vontor.cz', "https://www.vontor.cz", "https://peerjs.vontor.cz"]
if DEBUG:
ALLOWED_HOSTS.extend(["localhost", "127.0.0.1"])
CSRF_TRUSTED_ORIGINS.extend(["http://localhost:8000"])
#bezpečnost/SSL
if SSL is True:
print("SSL turned on!")
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
else:
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
SECURE_SSL_REDIRECT = False
SECURE_BROWSER_XSS_FILTER = False
SECURE_CONTENT_TYPE_NOSNIFF = False
USE_X_FORWARDED_HOST = False
# Application definition
MY_CREATED_APPS = [
'api',
'home',
]
INSTALLED_APPS = [
'daphne', #asgi bude fungovat lokálně (musí být na začátku)
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',#cors
#'chat.apps.GlobalChatCheck', #tohle se spusti při každé django inicializaci (migration, createmigration, runserver)
#'authentication',
'storages',# Adds support for external storage services like Amazon S3 via django-storages
'channels' ,# django channels
'rest_framework',
'rest_framework_api_key',
'django.contrib.sitemaps',
'tinymce',
#kvůli bugum je lepší to dát na poslední místo v INSTALLED_APPS
'django_cleanup.apps.CleanupConfig', #app která maže nepoužité soubory(media) z databáze na S3
]
INSTALLED_APPS = INSTALLED_APPS[:-1] + MY_CREATED_APPS + INSTALLED_APPS[-1:]
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",# Middleware that allows your backend to accept requests from other domains (CORS)
"django.middleware.common.CommonMiddleware",
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
#CUSTOM
#'tools.middleware.CustomMaxUploadSizeMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',# díky tomu funguje načítaní static files
]
# Caching settings for Redis (using Docker's internal network name for Redis)
if DEBUG is False:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://redis:6379/0', # Using the service name `redis` from Docker Compose
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PASSWORD': os.getenv('REDIS_PASSWORD'), # Make sure to set REDIS_PASSWORD in your environment
},
}
}
# WebSockets Channel Layers (using Redis in production)
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [('redis', 6379)], # Use `redis` service in Docker Compose
},
}
}
else:
# Use in-memory channel layer for development (when DEBUG is True)
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels.layers.InMemoryChannelLayer',
}
}
# Use in-memory cache for development (when DEBUG is True)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}
ROOT_URLCONF = 'vontor_cz.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
"DIRS": [BASE_DIR / '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',
],
},
},
]
ASGI_APPLICATION = 'vontor_cz.asgi.application' #daphne
DATABASES = {
'default': {
'ENGINE': os.getenv('DATABASE_ENGINE'),
'NAME': os.getenv('DATABASE_NAME'),
'USER': os.getenv('DATABASE_USER'),
'PASSWORD': os.getenv('DATABASE_PASSWORD'),
'HOST': os.getenv('DATABASE_HOST'),
'PORT': os.getenv('DATABASE_PORT'),
}
}
#DATABASE HEALTCHECK
try:
# Check if the default database connection is working
connection = connections['default']
print("-------------------------\nDatabase host: " + os.getenv('DATABASE_HOST'))
print(connection)
connection.ensure_connection()
print("Database connection is successful.")
except OperationalError:
print("Database connection failed!")
raise Exception("Database connection not available, shutting down!")
print("-------------------------")
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication', # For admin or user auth
'rest_framework_api_key.permissions.HasAPIKey', # For API key auth
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny', # Public access by default
]
}
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' #SMTP
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = 465
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
EMAIL_HOST_USER = os.getenv("EMAIL_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_USER_PASSWORD")
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER # Optional, if you want a default sender
EMAIL_TIMEOUT = 20
#AUTH_USER_MODEL = 'api.User'
# Password validation
# https://docs.djangoproject.com/en/4.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',
},
]
AUTHENTICATION_BACKENDS = [
'vontor_cz.backend.EmailOrUsernameModelBackend', #custom backend z authentication aplikace
'django.contrib.auth.backends.ModelBackend',
]
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Prague'
USE_I18N = True
USE_TZ = True
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
SESSION_COOKIE_AGE = 86400 # one day
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
LOGIN_URL = 'login'
#---------------------MEDIA + STATIC, AWS--------------------------
# Static files directories
STATICFILES_DIRS = [
BASE_DIR / 'globalstaticfiles',
]
# Include app-specific static files (excluding certain apps like django or rest_framework)
for app in settings.INSTALLED_APPS:
if app.startswith('django.') or 'rest_framework' in app or '.' in app:
continue
app_path = Path(BASE_DIR, app.replace('.', '/'))
static_path = app_path / 'static'
if static_path.exists():
STATICFILES_DIRS.append(static_path)
# Production / Development settings
if DEBUG:
# Development: Use local file system storage for static files
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
},
}
# Media and Static URL for local dev
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
# Local folder for collected static files
STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'
elif DEBUG is False:
AWS_LOCATION = "static"
# Production: Use S3 storage
STORAGES = {
"default": {
"BACKEND" : "storages.backends.s3boto3.S3StaticStorage",
},
"staticfiles": {
"BACKEND" : "storages.backends.s3boto3.S3StaticStorage",
},
}
# Media and Static URL for AWS S3
MEDIA_URL = f'https://{os.getenv("AWS_STORAGE_BUCKET_NAME")}.s3.amazonaws.com/media/'
STATIC_URL = f'https://{os.getenv("AWS_STORAGE_BUCKET_NAME")}.s3.amazonaws.com/static/'
# Static files should be collected to a local directory and then uploaded to S3
STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME', 'us-east-1') # Default to 'us-east-1' if not set
AWS_S3_SIGNATURE_VERSION = 's3v4' # Use AWS Signature Version 4
AWS_S3_USE_SSL = True
AWS_S3_FILE_OVERWRITE = True
AWS_DEFAULT_ACL = None # Set to None to avoid setting a default ACL
print(f"Static url: {STATIC_URL}\nStatic storage:{STORAGES}\n.............")
#--------------------END-MEDIA-STATIC-SECTION------------------
TINYMCE_JS_URL = 'https://cdn.tiny.cloud/1/no-api-key/tinymce/7/tinymce.min.js'
TINYMCE_DEFAULT_CONFIG = {
"height": "320px",
"width": "960px",
"menubar": "file edit view insert format tools table help",
"plugins": "advlist autolink lists link image charmap print preview anchor searchreplace visualblocks code "
"fullscreen insertdatetime media table paste code help wordcount spellchecker",
"toolbar": "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft "
"aligncenter alignright alignjustify | outdent indent | numlist bullist checklist | forecolor "
"backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | "
"fullscreen preview save print | insertfile image media pageembed template link anchor codesample | "
"a11ycheck ltr rtl | showcomments addcomment code",
"custom_undo_redo_levels": 10,
}
TINYMCE_SPELLCHECKER = True
TINYMCE_COMPRESSOR = True