""" 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 = True 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