Skripte nach bin/ und lib/ umstrukturiert + WSL-Log-Analyse Alle .bat-Skripte liegen jetzt in bin/, alle .py in lib/, .env(.example) in bin/. setenv.bat setzt IWZ_* (inkl. IWZ_ENV) und PYTHONPATH; die Launcher rufen setenv, aktivieren die .venv falls vorhanden und starten das zugehoerige lib/-Skript. Die Python-Skripte lesen die .env ueber IWZ_ENV (Fallback bin/.env). Neu: Nutzungsanalyse per GoAccess (analyze.py/.bat) - laedt die IONOS-Access-Logs per SFTP (paramiko) und erzeugt einen HTML-Report. GoAccess laeuft ueber WSL (GOACCESS_MODE=wsl, Pfad-Uebersetzung nach /mnt/c). install_py.bat prueft WSL+GoAccess und zeigt sonst den Installationsweg. Doku in doc/analyse.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> @
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
IWZ Ferienwohnungen - erzeugt einen befristeten, signierten Vorschau-Link
|
|
fuer die per Bunny Token Authentication geschuetzte Pull Zone.
|
|
"""
|
|
|
|
import base64
|
|
import hashlib
|
|
import os
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent # Skript liegt in lib/
|
|
GUELTIGKEIT_SEKUNDEN = 7 * 24 * 60 * 60 # 7 Tage
|
|
URL_PATH = "/"
|
|
|
|
|
|
def env_file():
|
|
"""Pfad zur .env: bevorzugt IWZ_ENV (von setenv.bat), sonst bin/.env."""
|
|
from_var = os.environ.get("IWZ_ENV")
|
|
if from_var:
|
|
return Path(from_var)
|
|
return PROJECT_ROOT / "bin" / ".env"
|
|
|
|
|
|
def load_env(path):
|
|
env = {}
|
|
if not path.exists():
|
|
return env
|
|
for line in path.read_text(encoding="utf-8").splitlines():
|
|
line = line.strip()
|
|
if not line or line.startswith("#") or "=" not in line:
|
|
continue
|
|
key, value = line.split("=", 1)
|
|
env[key.strip()] = value.strip()
|
|
return env
|
|
|
|
|
|
def build_signed_url(pull_zone_url, auth_key, url_path, expires):
|
|
hashable = f"{auth_key}{url_path}{expires}"
|
|
token_hash = hashlib.sha256(hashable.encode()).digest()
|
|
token = base64.urlsafe_b64encode(token_hash).decode().rstrip("=")
|
|
return f"{pull_zone_url}{url_path}?token={token}&expires={expires}"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
env = load_env(env_file())
|
|
pull_zone_url = env.get("BUNNY_PULL_ZONE_URL", "").rstrip("/")
|
|
auth_key = env.get("BUNNY_AUTH_KEY")
|
|
|
|
if not pull_zone_url or not auth_key:
|
|
print("\nFEHLER: BUNNY_PULL_ZONE_URL / BUNNY_AUTH_KEY fehlen in bin/.env.")
|
|
print("Siehe .env.example. Auth Key: Pull Zone -> Security -> Token Authentication.")
|
|
sys.exit(1)
|
|
|
|
expires = int(time.time()) + GUELTIGKEIT_SEKUNDEN
|
|
link = build_signed_url(pull_zone_url, auth_key, URL_PATH, expires)
|
|
|
|
gueltig_bis = time.strftime("%d.%m.%Y %H:%M", time.localtime(expires))
|
|
print("\n=== Vorschau-Link (Bunny Token Authentication) ===\n")
|
|
print(link)
|
|
print(f"\nGueltig bis: {gueltig_bis}\n")
|