Seite auf bunny laufen lassen. Konzept umgestellt
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
public/
|
||||
resources/
|
||||
.hugo_build.lock
|
||||
.env
|
||||
|
||||
@@ -8,12 +8,12 @@ Drei Ferienwohnungen in Kaufbeuren-Hirschzell / Allgäu.
|
||||
## Stack
|
||||
|
||||
- **Static Site Generator**: Hugo (keine externe Abhängigkeit, einzelne .exe)
|
||||
- **Hosting**: Cloudflare Pages (kostenlos, automatisches HTTPS)
|
||||
- **DNS**: Cloudflare (Nameserver-Wechsel von IONOS zu Cloudflare)
|
||||
- **Domain-Registrar**: IONOS (bleibt so, nur DNS wandert zu Cloudflare)
|
||||
- **Hosting**: Bunny.net (Bunny CDN / Storage Zone, kostenpflichtig nach Traffic)
|
||||
- **DNS**: Bunny.net DNS oder weiterhin IONOS (siehe Umzug-Notizen, ggf. anzupassen)
|
||||
- **Domain-Registrar**: IONOS (bleibt so)
|
||||
- **Buchungskalender**: webplanner.de (externer Dienst, per Link eingebunden)
|
||||
- **Git**: eigene Gitea-Instanz (kein GitHub/GitLab)
|
||||
- **Deploy**: manuell per `deploy.bat` oder `deploy.py` → `wrangler pages deploy`
|
||||
- **Git**: eigene Gitea-Instanz (kein GitHub/GitLab, kein CI/CD-Workflow)
|
||||
- **Deploy**: manuell per `deploy.bat` oder `deploy.py` → `hugo --gc --minify` + Upload nach Bunny.net Storage Zone (per Bunny-API/FTP, analog zum Ansatz in `.github/workflows/deploy.yml`-Vorlage, aber lokal statt als GitHub Action)
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
@@ -72,8 +72,11 @@ bilder:
|
||||
- [x] Telefon, E-Mail, Adresse in `hugo.toml` unter `[params]` eintragen
|
||||
- [x] `content/impressum.md` mit echten Pflichtangaben füllen
|
||||
- [x] `content/datenschutz.md` durch rechtskonforme Version ersetzen
|
||||
- [ ] Cloudflare-Account anlegen + Wrangler einrichten (`wrangler login`)
|
||||
- [ ] Nameserver bei IONOS auf Cloudflare umstellen
|
||||
- [x] Bunny.net-Account anlegen + Storage Zone für die Seite erstellen
|
||||
- [x] Bunny Storage-Passwort besorgen, sicher hinterlegen (`.env`, nicht ins Git)
|
||||
- [x] `deploy.bat` / `deploy.py` um Upload zur Bunny Storage Zone erweitern (FTP, Port 21, passiv)
|
||||
- [ ] Bunny Pull Zone / CDN vor die Storage Zone schalten (Auslieferung + HTTPS)
|
||||
- [ ] Domain-Anbindung an Bunny klären (DNS bei IONOS auf Bunny zeigen lassen, oder DNS zu Bunny umziehen)
|
||||
|
||||
## Lokaler Dev-Server
|
||||
|
||||
@@ -84,9 +87,12 @@ hugo server
|
||||
|
||||
## Deploy
|
||||
|
||||
Deploy läuft lokal per Skript (kein CI/CD, da Repo bei Gitea liegt). Referenz für den Bunny-Upload-Schritt ist die Vorlage `.github/workflows/deploy.yml` (GitHub-Actions-Syntax), deren Build- und Deploy-Logik 1:1 in `deploy.bat`/`deploy.py` nachgebaut wird:
|
||||
|
||||
```powershell
|
||||
# Einmalig:
|
||||
wrangler login
|
||||
hugo --gc --minify
|
||||
# danach: Upload von ./public zur Bunny.net Storage Zone
|
||||
# (Storage Zone Name + API-Key/Storage-Passwort als Secrets/env, nicht im Git)
|
||||
|
||||
# Bei jeder Änderung:
|
||||
deploy.bat
|
||||
|
||||
@@ -1,16 +1,166 @@
|
||||
# SSL/HTTPS auf Cloudflare Pages
|
||||
# Bunny.net – Ersteinrichtung und Vorab-Veröffentlichung
|
||||
|
||||
Ziel: `iwz-ferienwohnungen` bei Bunny.net anlegen, eine erste Fassung der Hugo-Seite
|
||||
online stellen und den Zugriff darauf auf dich + den Kunden beschränken (Vorschau,
|
||||
bevor die Seite öffentlich unter der echten Domain läuft).
|
||||
|
||||
> Hinweis: Dieser Weg ersetzt den früher geplanten Cloudflare-Pages-Ansatz.
|
||||
> Details zum alten Cloudflare/IONOS-Plan siehe weiter unten im Abschnitt
|
||||
> "Alt: Cloudflare-Variante (nicht mehr aktuell)".
|
||||
|
||||
## 1. Bunny.net-Account anlegen
|
||||
|
||||
1. Auf [bunny.net](https://bunny.net) registrieren (E-Mail + Passwort, keine
|
||||
Kreditkarte für den Start nötig, Abrechnung erfolgt nach Traffic/Storage).
|
||||
2. E-Mail-Adresse bestätigen und einloggen ins Dashboard.
|
||||
|
||||
## 2. Storage Zone anlegen (Ablage für die gebauten Hugo-Dateien)
|
||||
|
||||
1. Im Dashboard-Menü **Storage** → **Add Storage Zone**.
|
||||
2. Name vergeben, z. B. `iwz-ferienwohnungen`.
|
||||
3. **Main Region**: Region wählen, die am nächsten an euch/den Besuchern liegt
|
||||
(z. B. Frankfurt/Falkenstein, Europa).
|
||||
4. Replikations-Regionen optional dazuwählen, falls später Besucher aus anderen
|
||||
Kontinenten erwartet werden (für die Vorschau-Phase nicht nötig).
|
||||
5. Zone erstellen.
|
||||
|
||||
## 3. Zugangsdaten der Storage Zone notieren
|
||||
|
||||
1. Storage Zone öffnen → Reiter **FTP & API Access**.
|
||||
2. **Hostname**, **Username** und **Password** (nicht das Read-only-Passwort!)
|
||||
notieren – diese werden später für den Upload per `deploy.bat`/`deploy.py`
|
||||
gebraucht (als `BUNNY_STORAGE_ZONE` und `BUNNY_API_KEY`, siehe CLAUDE.md).
|
||||
3. Zugangsdaten **nicht** ins Git-Repo einchecken (z. B. in `.env` oder als
|
||||
Windows-Umgebungsvariable ablegen).
|
||||
|
||||
## 4. Erste Fassung hochladen
|
||||
|
||||
Lokal die Seite bauen und die `public/`-Inhalte in die Storage Zone hochladen:
|
||||
|
||||
```powershell
|
||||
hugo --gc --minify
|
||||
```
|
||||
|
||||
Für den allerersten Test kann der Upload manuell per **File Manager** im Bunny-
|
||||
Dashboard (Storage Zone → Files → Drag & Drop von `public/`) erfolgen. Sobald
|
||||
`deploy.bat`/`deploy.py` entsprechend erweitert ist, übernimmt das Skript diesen
|
||||
Schritt automatisch (Ordnerinhalt von `public/` 1:1 in die Storage Zone spiegeln).
|
||||
|
||||
## 5. Pull Zone anlegen (macht die Storage Zone über HTTPS erreichbar)
|
||||
|
||||
1. In der Storage Zone → **Connected Pull Zones** → **Connect Pull Zone**
|
||||
(oder im Menü **CDN → Add Pull Zone** und als Origin die Storage Zone wählen).
|
||||
2. Namen vergeben, z. B. `iwz-ferienwohnungen`.
|
||||
3. Zonen für die Auslieferung wählen (Europa reicht für die Vorschau).
|
||||
4. Pull Zone erstellen → Bunny vergibt automatisch eine Test-URL:
|
||||
`https://iwz-ferienwohnungen.b-cdn.net`
|
||||
5. HTTPS ist auf dieser `b-cdn.net`-URL automatisch aktiv, kein eigenes
|
||||
Zertifikat nötig.
|
||||
|
||||
Damit ist die Seite technisch live – als nächstes wird sie geschützt, bevor der
|
||||
Link an den Kunden geht.
|
||||
|
||||
## 6. Zugriff beschränken: nur du + der Kunde
|
||||
|
||||
Bunny.net Pull Zones bieten dafür **Token Authentication**: Requests an die
|
||||
Pull Zone werden nur ausgeliefert, wenn die URL einen gültigen, signierten Token
|
||||
enthält. Es gibt keinen klassischen Basic-Auth-Login-Dialog im Browser –
|
||||
stattdessen bekommt der Kunde einen fertigen Link mit Token, der bis zu einem
|
||||
festgelegten Ablaufzeitpunkt gültig ist.
|
||||
|
||||
### 6.1 Token Authentication aktivieren
|
||||
|
||||
1. Pull Zone öffnen → Reiter **Security**.
|
||||
2. **Token Authentication** aktivieren.
|
||||
3. Den angezeigten **Authentication Key** kopieren und sicher aufbewahren
|
||||
(nicht ins Git-Repo, nicht per unverschlüsselter Mail verschicken) – wer
|
||||
diesen Key kennt, kann selbst gültige Links erzeugen.
|
||||
|
||||
Ab jetzt liefert die Pull Zone **nichts mehr aus**, ohne gültigen Token in der
|
||||
URL – das ist der eigentliche Zugriffsschutz.
|
||||
|
||||
### 6.2 Signierten Link erzeugen
|
||||
|
||||
Ein signierter Link besteht aus einem Hash über `Authentication Key + Pfad +
|
||||
Ablaufzeitpunkt`. Das lässt sich einfach per kleinem Python-Snippet erzeugen,
|
||||
z. B. lokal ausführen, wenn ein neuer Vorschau-Link für den Kunden gebraucht
|
||||
wird:
|
||||
|
||||
```python
|
||||
import hashlib
|
||||
import base64
|
||||
import time
|
||||
|
||||
security_key = "DEIN_AUTHENTICATION_KEY"
|
||||
url_path = "/index.html" # z.B. Startseite, oder "/" je nach Setup
|
||||
expires = int(time.time()) + 7 * 24 * 60 * 60 # 7 Tage gültig
|
||||
|
||||
hashable = f"{security_key}{url_path}{expires}"
|
||||
token_hash = hashlib.sha256(hashable.encode()).digest()
|
||||
token = base64.urlsafe_b64encode(token_hash).decode().rstrip("=")
|
||||
|
||||
print(f"https://iwz-ferienwohnungen.b-cdn.net{url_path}?token={token}&expires={expires}")
|
||||
```
|
||||
|
||||
Den ausgegebenen Link schickst du dem Kunden. Läuft die Gültigkeit ab, einfach
|
||||
ein neues Snippet mit neuem `expires`-Wert ausführen und den frischen Link
|
||||
verschicken.
|
||||
|
||||
### 6.3 Praktisch für Vorschau-Zwecke
|
||||
|
||||
- Länge der Gültigkeit (`expires`) nach Bedarf wählen – z. B. 7 Tage für eine
|
||||
kurze Abstimmungsrunde, oder wenige Stunden für einen einzelnen Termin.
|
||||
- Ohne gültigen Token bekommt jeder andere Besucher einen Fehler von Bunny –
|
||||
die Seite ist damit faktisch nur über den geteilten Link erreichbar.
|
||||
- Sobald die Seite live gehen soll (echte Domain, öffentlich), wird Token
|
||||
Authentication in der Pull Zone einfach wieder deaktiviert.
|
||||
|
||||
## 7. Domain-Anbindung (später, für den echten Umzug)
|
||||
|
||||
Noch offen und erst relevant, wenn die Seite final ist:
|
||||
|
||||
- Eigene Domain (`iwz-ferienwohnungen.de`) als Custom Hostname in der Pull Zone
|
||||
hinterlegen.
|
||||
- Entweder DNS bei IONOS per CNAME auf die Bunny-Pull-Zone zeigen lassen, oder
|
||||
DNS komplett zu Bunny.net DNS umziehen (Nameserver-Wechsel bei IONOS,
|
||||
ähnlich wie ursprünglich für Cloudflare geplant).
|
||||
- SSL-Zertifikat für die eigene Domain wird von Bunny automatisch ausgestellt,
|
||||
sobald der Hostname verifiziert ist.
|
||||
- Domain-Registrar bleibt in jedem Fall IONOS.
|
||||
|
||||
## Zusammenfassung des Stacks (aktuell)
|
||||
|
||||
```
|
||||
Domain-Registrar: IONOS (bleibt so)
|
||||
DNS: noch offen (IONOS bleibt vorerst / später ggf. Bunny.net DNS)
|
||||
Hosting: Bunny.net (Storage Zone + Pull Zone/CDN)
|
||||
Vorschau-Schutz: Bunny Token Authentication (signierte, befristete Links)
|
||||
Code/Content: Gitea (eigene Instanz, kein CI/CD-Workflow)
|
||||
Deploy: manuell per deploy.bat / deploy.py (hugo build + Upload zur Storage Zone)
|
||||
Buchungskalender: webplanner.de (bleibt so, extern)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Alt: Cloudflare-Variante (nicht mehr aktuell)
|
||||
|
||||
Der folgende Abschnitt beschreibt den ursprünglich geplanten Umzug auf
|
||||
Cloudflare Pages und wird nicht mehr weiterverfolgt (Entscheidung: Umstieg auf
|
||||
Bunny.net, siehe oben). Als Referenz stehen gelassen.
|
||||
|
||||
## SSL/HTTPS auf Cloudflare Pages
|
||||
|
||||
Ja, vollautomatisch. Es gibt keine Tokens oder Zertifikate, die du selbst beantragen oder verlängern musst. Das läuft komplett im Hintergrund über Let's Encrypt, gesteuert von Cloudflare. Du siehst davon nichts.
|
||||
|
||||
# DNS und IP-Adresse — das ist der entscheidende Teil
|
||||
## DNS und IP-Adresse — das ist der entscheidende Teil
|
||||
|
||||
Hier gibt es zwei verschiedene Szenarien:
|
||||
|
||||
## Szenario A: Domain bei einem anderen Registrar (z.B. IONOS, Strato, Hetzner)
|
||||
### Szenario A: Domain bei einem anderen Registrar (z.B. IONOS, Strato, Hetzner)
|
||||
|
||||
Du hast zwei Möglichkeiten:
|
||||
|
||||
### Option 1 — Nameserver umziehen (empfohlen):
|
||||
#### Option 1 — Nameserver umziehen (empfohlen):
|
||||
Beim Registrar trägst du statt dessen Nameserver die Cloudflare-Nameserver ein:
|
||||
|
||||
aria.ns.cloudflare.com
|
||||
@@ -20,10 +170,10 @@ Danach verwaltest du alle DNS-Einträge bei Cloudflare. Cloudflare kennt dann de
|
||||
|
||||
www → dein-projekt.pages.dev
|
||||
|
||||
### Option 2 — Nur einen CNAME/A-Record setzen (ohne Nameserver-Wechsel):
|
||||
#### Option 2 — Nur einen CNAME/A-Record setzen (ohne Nameserver-Wechsel):
|
||||
Beim Registrar trägst du einen CNAME auf dein-projekt.pages.dev ein. Cloudflare Pages erkennt die Domain und stellt trotzdem ein Zertifikat aus — dauert aber etwas länger zur Verifizierung.
|
||||
|
||||
## Szenario B: Domain direkt bei Cloudflare registriert
|
||||
### Szenario B: Domain direkt bei Cloudflare registriert
|
||||
|
||||
Dann ist alles von Anfang an in einem Dashboard, kein Umzug nötig.
|
||||
|
||||
@@ -45,9 +195,7 @@ Danach läuft alles von selbst — das Zertifikat verlängert sich alle 90 Tage
|
||||
|
||||
# Wo ist die Domain iwz-ferienwohnungen.de aktuell registriert?
|
||||
|
||||
|
||||
|
||||
## Ablauf IONOS
|
||||
## Ablauf IONOS
|
||||
|
||||
Nameserver-Wechsel bei IONOS zu Cloudflare
|
||||
### Schritt 1: Cloudflare-Account anlegen und Domain hinzufügen
|
||||
@@ -76,11 +224,11 @@ IONOS bleibt weiterhin dein Domain-Registrar — das ist wichtig zu verstehen. D
|
||||
|
||||
Falls über IONOS auch E-Mail-Adressen laufen (z.B. info@iwz-ferienwohnungen.de), dann müssen die MX-Einträge beim Import in Cloudflare korrekt übernommen werden. Cloudflare importiert die normalerweise automatisch, aber das solltest du einmal kontrollieren bevor du den Nameserver-Wechsel machst. Die E-Mail funktioniert dann wie bisher — Cloudflare leitet den Mail-Verkehr nur weiter, hostet ihn nicht selbst.
|
||||
|
||||
# Zusammenfassung des gesamten Stacks
|
||||
# Zusammenfassung des gesamten Stacks (alt, Cloudflare)
|
||||
Domain-Registrar: IONOS (bleibt so)
|
||||
DNS + SSL: Cloudflare (kostenlos)
|
||||
Hosting: Cloudflare Pages (kostenlos)
|
||||
Code/Content: GitHub Repository (kostenlos)
|
||||
Buchungskalender: webplanner.de (bleibt so, extern)
|
||||
|
||||
Laufende Kosten danach: *nur noch die Domain-Verlängerung bei IONOS* (~10–15 € pro Jahr).
|
||||
Laufende Kosten danach: *nur noch die Domain-Verlängerung bei IONOS* (~10–15 € pro Jahr).
|
||||
|
||||
+2
-14
@@ -1,22 +1,10 @@
|
||||
@echo off
|
||||
echo.
|
||||
echo === IWZ Ferienwohnungen – Deploy ===
|
||||
echo === IWZ Ferienwohnungen - Deploy ===
|
||||
echo.
|
||||
echo Hugo Build...
|
||||
hugo
|
||||
python deploy.py
|
||||
if %errorlevel% neq 0 (
|
||||
echo FEHLER: Hugo Build fehlgeschlagen!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo.
|
||||
echo Deploy zu Cloudflare Pages...
|
||||
wrangler pages deploy public/ --project-name iwz-ferienwohnungen
|
||||
if %errorlevel% neq 0 (
|
||||
echo FEHLER: Deploy fehlgeschlagen!
|
||||
pause
|
||||
exit /b 1
|
||||
)
|
||||
echo.
|
||||
echo Fertig! Seite ist live.
|
||||
pause
|
||||
|
||||
@@ -1,25 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
IWZ Ferienwohnungen – Deploy Script
|
||||
Baut die Hugo-Seite und deployt sie zu Cloudflare Pages.
|
||||
IWZ Ferienwohnungen - Deploy Script
|
||||
Baut die Hugo-Seite und deployt sie per FTP zur Bunny.net Storage Zone.
|
||||
"""
|
||||
|
||||
import ftplib
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT = "iwz-ferienwohnungen"
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent
|
||||
PUBLIC_DIR = PROJECT_ROOT / "public"
|
||||
FTP_PORT = 21
|
||||
|
||||
|
||||
def run(cmd, desc):
|
||||
print(f"\n→ {desc}...")
|
||||
result = subprocess.run(cmd, shell=True)
|
||||
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 hugo_build():
|
||||
print("\n-> Hugo Build...")
|
||||
result = subprocess.run("hugo --gc --minify", shell=True)
|
||||
if result.returncode != 0:
|
||||
print(f"\nFEHLER bei: {desc}")
|
||||
print("\nFEHLER: Hugo Build fehlgeschlagen!")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def ftp_upload_dir(ftp, local_dir, remote_dir=""):
|
||||
for entry in sorted(local_dir.iterdir()):
|
||||
remote_path = f"{remote_dir}/{entry.name}" if remote_dir else entry.name
|
||||
if entry.is_dir():
|
||||
try:
|
||||
ftp.mkd(remote_path)
|
||||
except ftplib.error_perm:
|
||||
pass # existiert bereits
|
||||
ftp_upload_dir(ftp, entry, remote_path)
|
||||
else:
|
||||
with open(entry, "rb") as f:
|
||||
ftp.storbinary(f"STOR {remote_path}", f)
|
||||
print(f" {remote_path}")
|
||||
|
||||
|
||||
def deploy_to_bunny(host, zone, password):
|
||||
print(f"\n-> Deploy zu Bunny.net Storage Zone '{zone}'...")
|
||||
with ftplib.FTP() as ftp:
|
||||
ftp.connect(host, FTP_PORT)
|
||||
ftp.login(zone, password)
|
||||
ftp.set_pasv(True)
|
||||
ftp_upload_dir(ftp, PUBLIC_DIR)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== IWZ Deploy ===")
|
||||
run("hugo", "Hugo Build")
|
||||
run(f'wrangler pages deploy public/ --project-name {PROJECT}', "Cloudflare Pages Deploy")
|
||||
print("\n✓ Fertig! Seite ist live.")
|
||||
|
||||
env = {**load_env(PROJECT_ROOT / ".env"), **os.environ}
|
||||
zone = env.get("BUNNY_STORAGE_ZONE")
|
||||
host = env.get("BUNNY_STORAGE_HOST", "storage.bunnycdn.com")
|
||||
password = env.get("BUNNY_STORAGE_PASSWORD")
|
||||
|
||||
if not zone or not password:
|
||||
print("\nFEHLER: BUNNY_STORAGE_ZONE / BUNNY_STORAGE_PASSWORD fehlen.")
|
||||
print("Siehe .env.example -> .env kopieren und befuellen.")
|
||||
sys.exit(1)
|
||||
|
||||
hugo_build()
|
||||
deploy_to_bunny(host, zone, password)
|
||||
|
||||
print("\nFertig! Seite ist live.")
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/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 sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent
|
||||
GUELTIGKEIT_SEKUNDEN = 7 * 24 * 60 * 60 # 7 Tage
|
||||
URL_PATH = "/"
|
||||
|
||||
|
||||
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(PROJECT_ROOT / ".env")
|
||||
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 .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")
|
||||
@@ -0,0 +1,8 @@
|
||||
@echo off
|
||||
echo.
|
||||
echo === IWZ Ferienwohnungen - Vorschau-Link erzeugen ===
|
||||
python preview_link.py
|
||||
echo.
|
||||
echo Link oben markieren und mit Strg+C kopieren.
|
||||
echo.
|
||||
cmd /k
|
||||
Reference in New Issue
Block a user