tools/anti-ai-lint.py: Python-Linter (stdlib + yq) prueft jede build/<domain>/index.html gegen die Blacklist in tools/anti-ai-blacklist.yaml. HTML wird via html.parser auf sichtbaren Text reduziert (Skripte/Styles werden ignoriert), dann werden Vokabel- Substrings (DE+EN, case-insensitive) und Regex-Patterns gematcht. Severity warn = Build geht durch, fail = Build bricht ab. Whitelist-Mechanismen: - HTML-Kommentar im Markup: <!-- anti-ai-allow: term1, term2 --> - Per-Site in site.yaml: anti_ai_allow: [term1, term2] Integration in build.sh als Schritt 4/4, mit --skip-lint fuer Notfaelle. Dockerfile installiert python3 zusaetzlich; nur im Builder-Stage, kein Effekt aufs Caddy-Image. Tests via tools/test-anti-ai-lint.sh: synthetische AI-Fixture wird korrekt geflagged, Whitelists unterdruecken Hits, fail-Severity triggert exit 1, neutraler Text exit 0. Initial-Lauf auf 59 bestehenden Sites: 2 warn (killusion.de "revolutionaer" in ironischem Kontext, kilofant.de "robust"), 0 fail. Cleanup ist Folge-Issue. README + docs/geo-seo-guideline.md aktualisiert mit der konkreten Tool-Position.
77 lines
2.3 KiB
Bash
Executable File
77 lines
2.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Build all sites: generate Caddyfile, render templates, prepare build/ directory
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
|
BUILD_DIR="$SCRIPT_DIR/build"
|
|
|
|
skip_lint=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--skip-lint) skip_lint=1 ;;
|
|
-h|--help)
|
|
echo "Usage: $0 [--skip-lint]"
|
|
echo " --skip-lint Skip the anti-AI text lint step (emergencies only)."
|
|
exit 0
|
|
;;
|
|
*) echo "Unknown argument: $arg" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
echo "=== Onepager Build ==="
|
|
|
|
# Clean build directory
|
|
rm -rf "$BUILD_DIR"
|
|
mkdir -p "$BUILD_DIR"
|
|
|
|
# 1. Generate Caddyfile
|
|
echo "[1/3] Generating Caddyfile..."
|
|
"$SCRIPT_DIR/generate-caddyfile.sh" "$SCRIPT_DIR/sites" > "$SCRIPT_DIR/Caddyfile"
|
|
echo " -> Caddyfile written"
|
|
|
|
# 2. Build each site
|
|
echo "[2/3] Building sites..."
|
|
count=0
|
|
for site_dir in "$SCRIPT_DIR/sites"/*/; do
|
|
[ -f "$site_dir/site.yaml" ] || continue
|
|
domain=$(basename "$site_dir")
|
|
template=$(yq -r '.template // "custom"' "$site_dir/site.yaml")
|
|
|
|
mkdir -p "$BUILD_DIR/$domain"
|
|
|
|
if [ "$template" = "custom" ]; then
|
|
# Copy everything except site.yaml
|
|
find "$site_dir" -maxdepth 1 -not -name site.yaml -not -path "$site_dir" -exec cp -r {} "$BUILD_DIR/$domain/" \;
|
|
echo " [custom] $domain"
|
|
else
|
|
template_file="$SCRIPT_DIR/templates/${template}.html"
|
|
if [ ! -f "$template_file" ]; then
|
|
echo " [ERROR] Template '$template' not found for $domain — skipping" >&2
|
|
continue
|
|
fi
|
|
"$SCRIPT_DIR/render.sh" "$site_dir/site.yaml" "$template_file" > "$BUILD_DIR/$domain/index.html"
|
|
# Copy assets if present
|
|
[ -d "$site_dir/assets" ] && cp -r "$site_dir/assets" "$BUILD_DIR/$domain/"
|
|
echo " [${template}] $domain"
|
|
fi
|
|
count=$((count + 1))
|
|
done
|
|
echo " -> $count sites built"
|
|
|
|
# 3. Copy shared assets
|
|
echo "[3/3] Copying shared assets..."
|
|
cp -r "$SCRIPT_DIR/shared" "$BUILD_DIR/shared"
|
|
echo " -> shared/ copied"
|
|
|
|
# 4. Anti-AI text lint
|
|
if [ "$skip_lint" -eq 1 ]; then
|
|
echo "[4/4] Anti-AI lint skipped (--skip-lint)"
|
|
elif ! command -v python3 >/dev/null 2>&1; then
|
|
echo "[4/4] python3 not found — skipping anti-AI lint"
|
|
else
|
|
echo "[4/4] Anti-AI text lint..."
|
|
python3 "$SCRIPT_DIR/tools/anti-ai-lint.py" "$BUILD_DIR"
|
|
fi
|
|
|
|
echo "=== Build complete: $count sites ==="
|