7c23c3f4c7
- Telegram-Bot (Polling) mit Inline-Menue: Klarbild x2/x4, Freistellen, kombiniert - Upscaling via OpenCV dnn_superres (FSRCNN default, EDSR optional), gekachelt - Freistellen via rembg (isnet-general-use, Alpha-Matting) - Picdrop-Batch via SFTP (/picdrop) - Health-Server (aiohttp) fuer Coolify, Zugriffsschutz via ALLOWED_USER_IDS - Dockerfile backt Modelle (SR von raw.githubusercontent, rembg von HF-Mirror) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNQ8ghPfzAfsyVYd6HgFb6
81 lines
3.2 KiB
Python
81 lines
3.2 KiB
Python
"""Zentrale Konfiguration aus Umgebungsvariablen."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
def _get_bool(name: str, default: bool = False) -> bool:
|
|
val = os.getenv(name)
|
|
if val is None:
|
|
return default
|
|
return val.strip().lower() in {"1", "true", "yes", "on", "ja"}
|
|
|
|
|
|
def _get_int(name: str, default: int) -> int:
|
|
try:
|
|
return int(os.getenv(name, str(default)))
|
|
except (TypeError, ValueError):
|
|
return default
|
|
|
|
|
|
# --- Telegram ---------------------------------------------------------------
|
|
BOT_TOKEN: str = os.getenv("BOT_TOKEN", "").strip()
|
|
|
|
# Kommagetrennte Liste erlaubter Telegram-User-IDs. Leer = jeder darf (nur
|
|
# fuer Tests empfohlen). /start zeigt jedem seine ID, damit man hier eintraegt.
|
|
_allowed = os.getenv("ALLOWED_USER_IDS", "").replace(";", ",")
|
|
ALLOWED_USER_IDS: set[int] = {
|
|
int(x) for x in (p.strip() for p in _allowed.split(",")) if x.strip().isdigit()
|
|
}
|
|
|
|
# --- Bild-Pipeline ----------------------------------------------------------
|
|
MODELS_DIR: Path = Path(os.getenv("MODELS_DIR", "/app/models"))
|
|
WORK_DIR: Path = Path(os.getenv("WORK_DIR", "/tmp/klarbild"))
|
|
|
|
# rembg-Modell fuers Freistellen: isnet-general-use (gut), u2net, u2netp (leicht),
|
|
# birefnet-general (beste Qualitaet, schwer). Wird beim Build vorgeladen.
|
|
REMBG_MODEL: str = os.getenv("REMBG_MODEL", "isnet-general-use")
|
|
|
|
# OpenCV dnn_superres: "fsrcnn" (schnell, Default) oder "edsr" (mehr Detail,
|
|
# aber auf CPU sehr langsam ~40s/Kachel -> nur fuer starke Boxen empfohlen).
|
|
UPSCALE_MODEL: str = os.getenv("UPSCALE_MODEL", "fsrcnn").lower()
|
|
|
|
# Optionales Real-ESRGAN-ONNX-Backend (fuer GPU/starke Boxen). Wenn aktiv und
|
|
# Modelldatei vorhanden, wird es statt OpenCV genutzt.
|
|
ENABLE_REALESRGAN: bool = _get_bool("ENABLE_REALESRGAN", False)
|
|
REALESRGAN_ONNX: Path = Path(
|
|
os.getenv("REALESRGAN_ONNX", str(MODELS_DIR / "realesrgan_x4.onnx"))
|
|
)
|
|
|
|
# Speicherschutz auf kleinen Boxen (CX33: 8GB, keine GPU):
|
|
# Laengste Kante des Eingangsbildes vor dem Upscalen begrenzen.
|
|
MAX_INPUT_EDGE: int = _get_int("MAX_INPUT_EDGE", 1600)
|
|
# Kachelgroesse fuer das Upscalen (kleiner = weniger RAM, mehr Overhead).
|
|
TILE_SIZE: int = _get_int("TILE_SIZE", 256)
|
|
# Deckel fuer die Ausgabe-Megapixel (Sicherheitsnetz gegen OOM).
|
|
MAX_OUTPUT_MP: float = float(os.getenv("MAX_OUTPUT_MP", "80"))
|
|
|
|
# Nach dem Upscalen leichte Entrauschung + Schaerfung ("Klarbild"-Finish).
|
|
POST_DENOISE: bool = _get_bool("POST_DENOISE", True)
|
|
POST_SHARPEN: bool = _get_bool("POST_SHARPEN", True)
|
|
|
|
# JPEG-Qualitaet fuer zurueckgesendete Fotos (Freistellen liefert immer PNG).
|
|
JPEG_QUALITY: int = _get_int("JPEG_QUALITY", 95)
|
|
|
|
# --- Health-Server ----------------------------------------------------------
|
|
HEALTH_PORT: int = _get_int("PORT", 8080)
|
|
|
|
# --- Picdrop (SFTP) ---------------------------------------------------------
|
|
PICDROP_HOST: str = os.getenv("PICDROP_HOST", "ftps.picdrop.com")
|
|
PICDROP_PORT: int = _get_int("PICDROP_PORT", 22)
|
|
PICDROP_USER: str = os.getenv("PICDROP_USER", "")
|
|
PICDROP_PASSWORD: str = os.getenv("PICDROP_PASSWORD", "")
|
|
PICDROP_ENABLED: bool = bool(PICDROP_USER and PICDROP_PASSWORD)
|
|
|
|
|
|
def validate() -> None:
|
|
if not BOT_TOKEN:
|
|
raise SystemExit("FEHLER: Umgebungsvariable BOT_TOKEN ist nicht gesetzt.")
|
|
WORK_DIR.mkdir(parents=True, exist_ok=True)
|