From 5e10f2eac73deda80b764569d8b92f031c4cf3a0 Mon Sep 17 00:00:00 2001 From: Egor fureunoir Gorbunov Date: Sat, 8 Nov 2025 05:06:58 +0300 Subject: [PATCH] Features: 1) Add `db_table` attribute for `vibes_auth_user` in `authv.models`; 2) Enhance DB backup configuration to support `sftp` and `ftp` storage in settings. Fixes: 1) Add missing import for `ImproperlyConfigured` in `base.py`. Extra: 1) Refactor and relocate DB backup configuration from `dbbackup.py` to `base.py`. --- engine/authv/models.py | 1 + evibes/settings/base.py | 64 +++++++++++++++++++++++++++++++++++-- evibes/settings/dbbackup.py | 45 -------------------------- 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/engine/authv/models.py b/engine/authv/models.py index 8a68313f..efe1b4d2 100644 --- a/engine/authv/models.py +++ b/engine/authv/models.py @@ -111,6 +111,7 @@ class User(AbstractUser, NiceModel): # type: ignore [django-manager-missing] return self.email class Meta: + db_table = "vibes_auth_user" swappable = "AUTH_USER_MODEL" verbose_name = _("user") verbose_name_plural = _("users") diff --git a/evibes/settings/base.py b/evibes/settings/base.py index 2e22b86f..fdddd9d3 100644 --- a/evibes/settings/base.py +++ b/evibes/settings/base.py @@ -4,6 +4,8 @@ from os import getenv, name from pathlib import Path from typing import Any +from django.core.exceptions import ImproperlyConfigured + EVIBES_VERSION = "2025.4" RELEASE_DATE = datetime(2025, 9, 13) @@ -407,11 +409,67 @@ STORAGES: dict[str, dict[str, str | int | bool | None]] = { if DEBUG else "whitenoise.storage.CompressedManifestStaticFilesStorage" }, - "dbbackup": { - "BACKEND": "django.core.files.storage.FileSystemStorage", - }, } +if getenv("DBBACKUP_HOST") and getenv("DBBACKUP_USER") and getenv("DBBACKUP_PASS"): + dbbackup_server_type = getenv("DBBACKUP_TYPE", "sftp") + project_name = getenv("EVIBES_PROJECT_NAME", "evibes_common").lower().replace(" ", "_") + + raw_path = getenv("DBBACKUP_PATH", f"/backups/{project_name}/") + cleaned = raw_path.strip("/") + remote_dir = f"{cleaned}/" + + match dbbackup_server_type: + case "sftp": + STORAGES.update( + { + "dbbackup": { + "BACKEND": "storages.backends.sftpstorage.SFTPStorage", + "OPTIONS": { + "host": getenv("DBBACKUP_HOST"), + "root_path": f"/{remote_dir}", + "params": { + "username": getenv("DBBACKUP_USER"), + "password": getenv("DBBACKUP_PASS"), + "allow_agent": False, + "look_for_keys": False, + }, + "interactive": False, + "file_mode": 0o600, + "dir_mode": 0o700, + }, + } + } + ) + + case "ftp": + STORAGES.update( + { + "dbbackup": { + "BACKEND": "evibes.ftpstorage.AbsoluteFTPStorage", + "OPTIONS": { + "location": ( + f"ftp://{getenv('DBBACKUP_USER')}:{getenv('DBBACKUP_PASS')}@{getenv('DBBACKUP_HOST')}:21/{raw_path}" + ), + }, + } + } + ) + + case _: + raise ImproperlyConfigured(f"Invalid DBBACKUP_TYPE: {dbbackup_server_type}") +else: + STORAGES.update( + { + "dbbackup": { + "BACKEND": "django.core.files.storage.FileSystemStorage", + "OPTIONS": { + "location": "/app/backups/", + }, + } + } + ) + if name == "nt": GDAL_LIBRARY_PATH = r"C:\OSGeo4W\bin\gdal311.dll" GEOS_LIBRARY_PATH = r"C:\OSGeo4W\bin\geos_c.dll" diff --git a/evibes/settings/dbbackup.py b/evibes/settings/dbbackup.py index fca73a7e..a8225a2f 100644 --- a/evibes/settings/dbbackup.py +++ b/evibes/settings/dbbackup.py @@ -1,6 +1,3 @@ -from os import getenv -from django.core.exceptions import ImproperlyConfigured - DBBACKUP_CONNECTORS = { "default": { "SINGLE_TRANSACTION": False, @@ -8,45 +5,3 @@ DBBACKUP_CONNECTORS = { "RESTORE_SUFFIX": "--set ON_ERROR_STOP=off", } } - -if getenv("DBBACKUP_HOST") and getenv("DBBACKUP_USER") and getenv("DBBACKUP_PASS"): - dbbackup_server_type = getenv("DBBACKUP_TYPE", "sftp") - project_name = getenv("EVIBES_PROJECT_NAME", "evibes_common").lower().replace(" ", "_") - - raw_path = getenv("DBBACKUP_PATH", f"/backups/{project_name}/") - cleaned = raw_path.strip("/") - remote_dir = f"{cleaned}/" - - match dbbackup_server_type: - case "sftp": - DBBACKUP_STORAGE = "storages.backends.sftpstorage.SFTPStorage" - DBBACKUP_STORAGE_OPTIONS = { - "host": getenv("DBBACKUP_HOST"), - "root_path": f"/{remote_dir}", - "params": { - "username": getenv("DBBACKUP_USER"), - "password": getenv("DBBACKUP_PASS"), - "allow_agent": False, - "look_for_keys": False, - }, - "interactive": False, - "file_mode": 0o600, - "dir_mode": 0o700, - } - - case "ftp": - DBBACKUP_STORAGE = "evibes.ftpstorage.AbsoluteFTPStorage" - DBBACKUP_STORAGE_OPTIONS = { - "location": ( - f"ftp://{getenv('DBBACKUP_USER')}:{getenv('DBBACKUP_PASS')}@{getenv('DBBACKUP_HOST')}:21/{raw_path}" - ), - } - - case _: - raise ImproperlyConfigured(f"Invalid DBBACKUP_TYPE: {dbbackup_server_type}") - -else: - DBBACKUP_STORAGE = "django.core.files.storage.FileSystemStorage" - DBBACKUP_STORAGE_OPTIONS = { - "location": "/app/backups/", - }