"""Настройки сервера, хранящиеся в БД (меняются админом в панели).""" import secrets from pathlib import Path from sqlalchemy.orm import Session from . import autoconf, config from .models import Setting DEFAULTS = { "photo_dir": config.PHOTO_DIR, "max_photo_mb": "10", "vapid_contact": "mailto:admin@example.com", "fcm_credentials_path": "", "public_incidents": "1", "backup_auto_hours": "24", # автокопия раз в N часов (0 — выключено) "backup_keep": "14", # сколько автокопий хранить "backup_media": "0", # включать ли в автокопию фото и картинки "setup_done": "", "crane_map": "0", # отдельная карта кранов "reliability": "1", # раздел «Анализ надёжности» для инженеров и руководителей "photo_keep_days": "0", # автоочистка: удалять фото нарядов и заданий старше N дней (0 — не удалять; keep/ не трогается) "photo_cleanup_at": "", # когда очистка выполнялась последний раз "crane_map_image": "", # картинка карты кранов (пусто — используется карта завода) # мастер первичной настройки: отмеченные шаги (через запятую) # AI-помощник (не входит в EDITABLE: ключ не отдаётся в общих настройках, правится через /assistant/config) "assistant_enabled": "0", "assistant_provider": "openai", "assistant_base_url": "", "assistant_model": "", "assistant_api_key": "", "assistant_scope": "", # документация из Nextcloud (не входит в EDITABLE: пароль и секрет не отдаются, правится через /docs/config) "nc_url": "", # адрес Nextcloud, лучше внутренний в локальной сети "nc_user": "", # служебная учётная запись (только чтение) "nc_password": "", # пароль приложения этой учётной записи "nc_root": "", # корневая папка документации внутри учётной записи "onlyoffice_url": "", # ONLYOFFICE Document Server — переводит документы Office в PDF для просмотра "onlyoffice_jwt": "", # секрет JWT Document Server (если включён) "portal_internal_url": "", # адрес портала, по которому его видит ONLYOFFICE (локальная сеть) "docs_ai": "0", # «Работа с документацией» для AI-помощника "docs_index_at": "", # когда последний раз строился индекс } EDITABLE = ("photo_dir", "max_photo_mb", "vapid_contact", "fcm_credentials_path", "public_incidents", "backup_auto_hours", "backup_keep", "backup_media", "setup_done", "crane_map", "reliability", "photo_keep_days") def get(db: Session, key: str) -> str: row = db.get(Setting, key) if row and row.value != "": return row.value auto = autoconf.default(key) # окружение (.env) или сервис во внутренней сети Docker return auto if auto is not None else DEFAULTS.get(key, "") def set_(db: Session, key: str, value: str): row = db.get(Setting, key) if row: row.value = value else: db.add(Setting(key=key, value=value)) def all_editable(db: Session) -> dict: return {k: get(db, k) for k in EDITABLE} def photo_root(db: Session) -> Path: p = Path(get(db, "photo_dir")) p.mkdir(parents=True, exist_ok=True) return p def new_name() -> str: return secrets.token_hex(16)