""" Django settings for monitoring project. Generated by 'django-admin startproject' using Django 5.1.6. 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/ """ from django.contrib.messages import constants as message_constants from pathlib import Path from decouple import config, Csv # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent print("Django BASE_DIR:", BASE_DIR) PACKAGE_DIR = BASE_DIR.parent APP_DATAS = PACKAGE_DIR / config('APP_DATAS') # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ DJANGO_APP = config('DJANGO_APP') APP_NAME = DJANGO_APP # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ SECRET_KEY = config("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! DEBUG = config('DEBUG', cast=bool) DOMAIN_SERVER = config("DOMAIN_SERVER") ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) ALLOWED_HOSTS += [DOMAIN_SERVER, '*'] CSRF_TRUSTED_ORIGINS = config('CSRF_TRUSTED_ORIGINS', cast=Csv()) CSRF_TRUSTED_ORIGINS += [f'http://{DOMAIN_SERVER}', f'https://{DOMAIN_SERVER}'] SECURE_CROSS_ORIGIN_OPENER_POLICY = 'same-origin' X_FRAME_OPTIONS = 'SAMEORIGIN' # Application definition INSTALLED_APPS = [ 'daphne', 'channels', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_celery_beat', 'django_celery_results', 'celery', 'home', 'scanner', 'planarian', ] AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', #'contrib.auth.EmailBackend', ) MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'home.middleware.SetDefaultLangMiddleware', ] ROOT_URLCONF = 'home.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', 'home.context_processors.params', ], }, }, ] WSGI_APPLICATION = 'home.wsgi.application' ASGI_APPLICATION = 'home.asgi.application' MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' # Redis # REDIS_HOST=config("REDIS_HOST") REDIS_PORT=int(config("REDIS_PORT")) CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [(REDIS_HOST, REDIS_PORT)], "capacity": 5000, # default 100 "expiry": 10, # default 60 }, }, } # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases DATABASE_NAME = config('DATABASE_NAME') DATABASE_USER = config('DATABASE_USER') DATABASE_PASSWORD = config('DATABASE_PASSWORD') SQLITE3=config('SQLITE3') SQLITE3_PATH=config('SQLITE3_PATH') MARIADB=config('MARIADB') POSTGRES=config('POSTGRES') DATABASES = { SQLITE3: { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': f'{SQLITE3_PATH}db.sqlite3', "OPTIONS": { "timeout": 20, }, }, MARIADB: { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS' : { "init_command": "SET foreign_key_checks = 0;SET sql_mode='STRICT_TRANS_TABLES';", 'charset': 'utf8mb4', }, 'NAME': DATABASE_NAME, 'USER': DATABASE_USER, 'PASSWORD': DATABASE_PASSWORD, 'HOST': config("DATABASE_MARIADB_HOST"), 'PORT': config("DATABASE_MARIADB_PORT", cast=int), }, POSTGRES: { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': DATABASE_NAME, 'USER': DATABASE_USER, 'PASSWORD': DATABASE_PASSWORD, 'HOST': config("DATABASE_POSTGRES_HOST"), 'PORT': config("DATABASE_POSTGRES_PORT", cast=int), }, } # Password validation # https://docs.djangoproject.com/en/5.1/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', }, ] # Internationalization # https://docs.djangoproject.com/en/5.1/topics/i18n/ #LANGUAGE_CODE = 'en-US' LANGUAGE_CODE = config('LANGUAGE_CODE') LANGUAGES = ( ('fr', 'Français'), ('en', 'English'), ) TIME_ZONE = config('TIME_ZONE') USE_I18N = True USE_L10N = True USE_TZ = True LOCALE_CODE = config('LOCALE_CODE') LOCALE_LC_ALL = config('LOCALE_LC_ALL') LOCALE_PATHS = ( BASE_DIR / 'home' / 'locale', ) # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.1/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = APP_DATAS / 'staticfiles' print("Django application STATIC_ROOT:", STATIC_ROOT) MEDIA_URL = '/media/' MEDIA_ROOT = APP_DATAS / 'media' print("Django application MEDIA_ROOT:", MEDIA_ROOT) """ STATICFILES_DIRS = [ BASE_DIR / 'xxx', ] """ # Default primary key field type # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' ## LOGGING # CRITICAL=50, ERROR=40, WARN=30, INFO=20, DEBUG=10 and NOTSET=0 LOGGING_FILE = config('LOGGING_FILE') IS_LOGGING = config('IS_LOGGING', cast=bool) LOGGING = None if not IS_LOGGING else { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': '%(asctime)s - %(message)s' }, "celery": { "format": "%(asctime)s [%(levelname)s] %(name)s — %(message)s", "datefmt": "%Y-%m-%d %H:%M:%S", }, }, 'handlers': { "celery_file": { "class" : "logging.handlers.RotatingFileHandler", "filename" : BASE_DIR / "logs" / "celery.log", "maxBytes" : 10 * 1024 * 1024, # 10 Mo par fichier "backupCount": 5, # 5 fichiers max en rotation "formatter" : "celery", "encoding" : "utf-8", }, 'file': { 'level': 'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': BASE_DIR / "logs" / LOGGING_FILE, 'maxBytes': 1024*1024*15, # 15MB 'backupCount': 10, 'formatter': 'simple', }, 'null': {'class': 'logging.NullHandler', }, 'console': {'class': 'logging.StreamHandler',}, }, 'loggers': { "django": {"handlers": ["file"], "level": "ERROR", "propagate": False,}, "uvicorn": {"handlers": ["file"], "level": "ERROR", "propagate": False,}, "daphne": {"handlers": ["file"], "level": "ERROR", "propagate": False,}, 'axes': {"handlers": ['file',],"level": "INFO", "propagate": True, }, "celery": {"handlers": ["celery_file"], "level": "INFO", "propagate": False,}, "celery.task": {"handlers": ["celery_file"], "level": "INFO", "propagate": False, }, "celery.worker": {"handlers": ["celery_file"], "level": "INFO", "propagate": False, }, "scanner": {"handlers": ["file"], "level": "INFO", "propagate": False,}, }, } # ACCOUNT # LOGIN_URL = 'login' LOGIN_REDIRECT_URL = '/' LOGOUT_REDIRECT_URL = "/" ## # application SUPERADMIN_MAIL = config('SUPERADMIN_MAIL') ADMINS = [ (SUPERADMIN_MAIL, config('SUPERADMIN'), config('SUPERADMIN_PASS'), True), ] MANAGERS = ADMINS # w3 css MESSAGE_TAGS = { message_constants.DEBUG: 'w3-purple', message_constants.INFO: 'w3-blue', message_constants.SUCCESS: 'w3-green', message_constants.WARNING: 'w3-orange', message_constants.ERROR: 'w3-red', } # Default css classes for widgets and labels DEFAULT_CSS = { 'error': 'w3-panel w3-red', # displayed in the label 'errorlist': 'w3-padding-8 w3-red', # encloses the error list 'required': 'w3-text-indigo', # used in the label and label + input enclosing box. NB: w3-validate only works if the input precedes the label! 'label': 'w3-label', 'Textarea': 'w3-input w3-border', 'TextInput': 'w3-input w3-border', 'Select': 'w3-select w3-border', } # django mail # DEFAULT_TO_EMAIL = config("DEFAULT_TO_EMAIL") DEFAULT_FROM_EMAIL = config("DEFAULT_FROM_EMAIL") DEFAULT_EMAIL_CONTACT = config("DEFAULT_EMAIL_CONTACT") EMAIL_BACKEND = config("EMAIL_BACKEND") EMAIL_HOST = config("EMAIL_HOST") EMAIL_PORT = config("EMAIL_PORT", cast=int) EMAIL_HOST_USER = config("EMAIL_HOST_USER") EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD") EMAIL_USE_TLS = config('EMAIL_USE_TLS', cast=bool) ## CELERY tasks # #from celery.schedules import crontab REDIS_HOST_PORT = f'{config("REDIS_HOST")}:{config("REDIS_PORT")}' CELERY_RESULT_BACKEND = f"redis://{REDIS_HOST_PORT}/1" CELERY_BROKER_URL = f"redis://{REDIS_HOST_PORT}/0" CELERY_TASK_RESULT_EXPIRES=3600 CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = False CELERY_TIMEZONE=TIME_ZONE DJANGO_CELERY_BEAT_TZ_AWARE = False CELERY_ENABLE_UTC = True CELERY_TASK_TRACK_STARTED = True CELERY_TASK_TIME_LIMIT = 30 * 60 CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_RESULT_SERIALIZER = 'json' CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_EXTENDED = True CELERY_RESULT_BACKEND = 'django-db' DJANGO_CELERY_RESULTS_TASK_ID_MAX_LENGTH=191 ## reductstore # REDUCTSTORE_TOKEN = config('REDUCTSTORE_TOKEN') REDUCTSTORE_HOST = config('REDUCTSTORE_HOST') REDUCTSTORE_PORT = config('REDUCTSTORE_PORT', cast=int) REDUCTSTORE_URL = f'http://{REDUCTSTORE_HOST}:{REDUCTSTORE_PORT}' REDUCTSTORE_PATH = config("REDUCTSTORE_PATH") ## servers app # USER = config('USER') GROUP = config('GROUP') SERVER_HOST_PORT = config('SERVER_HOST_PORT', cast=int) SERVER_HOST_IP = config('SERVER_HOST_IP') # ws SCANNER_WEBSOCKET_ROUTE = 'ws/scanner' REPLAY_WEBSOCKET_ROUTE = 'ws/replay' # app # DATA_UPLOAD_MAX_NUMBER_FIELDS = 10240 APP_TITLE = config("APP_TITLE") APP_SUB_TITLE = config("APP_SUB_TITLE") DATETIME_FORMAT = '%d-%m-%Y-%m %H:%M:%S' #=========================== # default configuration # #=========================== # rpicam 4056x3040 2028x1080 2028x1520 EXPORTS_LOCAL_PATH = config("EXPORTS_LOCAL_PATH") EXPORT_REMOTE_PATH = config("EXPORT_REMOTE_PATH") EXPORT_DESTINATIONS = ["local", "remote"] TEST_VIDEOFILE = False TRACKING = True TRACKER_TUBE_AXIS = "vertical" TRACKER_MIN_AREA = 200 CALIBRATION_AUTO_DURATION = 45.0 CALIBRATION_AUTO_TIMEOUT = 2.5