feat: add backups feature
This commit is contained in:
@@ -434,6 +434,55 @@ SETTINGS_MANIFEST: List[SettingField] = [
|
||||
"ID треда поддержки",
|
||||
"Тред лог-чата для уведомлений о тикетах поддержки.",
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_ENABLED",
|
||||
"bool",
|
||||
"backups",
|
||||
"Бэкапы включены",
|
||||
"Worker будет периодически собирать ZIP-архив и отправлять его в Telegram.",
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_CHAT_ID",
|
||||
"int",
|
||||
"backups",
|
||||
"ID чата для бэкапов",
|
||||
"Куда отправлять ZIP-архивы. Если пусто, используется LOG_CHAT_ID.",
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_THREAD_ID",
|
||||
"int",
|
||||
"backups",
|
||||
"ID треда для бэкапов",
|
||||
"Необязательный topic/thread ID. Если пусто, используется LOG_THREAD_ID.",
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_INTERVAL_SECONDS",
|
||||
"int",
|
||||
"backups",
|
||||
"Период бэкапов (сек.)",
|
||||
"По умолчанию 3600: запуск на границе часа (12:00, 13:00 и т.д.).",
|
||||
optional=False,
|
||||
min=60,
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_LOCAL_RETENTION",
|
||||
"int",
|
||||
"backups",
|
||||
"Сколько архивов хранить",
|
||||
"Сколько последних ZIP-архивов оставлять в data/backups на сервере.",
|
||||
optional=False,
|
||||
min=1,
|
||||
),
|
||||
SettingField(
|
||||
"BACKUP_COMPOSE_ENABLED",
|
||||
"bool",
|
||||
"backups",
|
||||
"Добавлять compose-папку",
|
||||
(
|
||||
"Добавляет snapshot /app/compose-source. Если папка не смонтирована, "
|
||||
"бэкап БД все равно будет создан."
|
||||
),
|
||||
),
|
||||
SettingField(
|
||||
"SUPPORT_TICKETS_ENABLED",
|
||||
"bool",
|
||||
@@ -561,6 +610,8 @@ def coerce_value(field: SettingField, raw: Any) -> Any:
|
||||
return text
|
||||
|
||||
if raw is None or (isinstance(raw, str) and raw.strip() == ""):
|
||||
if not field.optional:
|
||||
raise ValueError(f"{field.key}: value required")
|
||||
return None
|
||||
|
||||
if field.type == "bool":
|
||||
@@ -629,7 +680,8 @@ def manifest_payload() -> List[dict]:
|
||||
"referral": 6,
|
||||
"notifications": 7,
|
||||
"support": 8,
|
||||
"devices": 9,
|
||||
"backups": 9,
|
||||
"devices": 10,
|
||||
"subscription_guides": 10,
|
||||
}
|
||||
exclusive_map = {
|
||||
@@ -678,6 +730,10 @@ def manifest_payload() -> List[dict]:
|
||||
"optional": field.optional,
|
||||
"secret": field.secret,
|
||||
}
|
||||
if field.min is not None:
|
||||
item["min"] = field.min
|
||||
if field.max is not None:
|
||||
item["max"] = field.max
|
||||
if field.key in exclusive_map:
|
||||
item["mutually_exclusive_key"] = exclusive_map[field.key]
|
||||
if default_value is not None:
|
||||
|
||||
Reference in New Issue
Block a user