Files
search/clear_domain_suggestions.sh
2026-10-09 16:42:15 +02:00

143 lines
5.3 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# clear_domain_suggestions.sh
#
# Loescht ALLE Eintraege aus der Tabelle `domain_suggestions` — der
# Buchhaltungs-Tabelle des Vorschlagsverfeinerers (priorityweb/app.py,
# Port 8082). Die Liste "Letzte Vorschlaege" im Web-UI ist danach leer.
#
# WICHTIG: Die crawl_queue wird NICHT angefasst. Bereits priorisierte
# Domains bleiben mit Prioritaet 1000000 (SUGGEST_PRIORITY) vorne in
# der Queue und werden weiterhin als Naechstes gecrawlt. Falls auch
# diese Boosts aufgehoben werden sollen, zusaetzlich ausfuehren:
#
# DELETE FROM crawl_queue
# WHERE status = 'pending' AND priority >= 1000000;
#
# (Nur pending-Zeilen: laufende Verarbeitungen werden nicht abgeschossen.)
#
# Verwendung:
# ./clear_domain_suggestions.sh mit Rueckfrage
# ./clear_domain_suggestions.sh --yes ohne Rueckfrage (z. B. fuer Cron)
# ./clear_domain_suggestions.sh --help diesen Text anzeigen
#
# DB-Zugangsdaten kommen wie bei allen Komponenten aus der .env
# (JONASSEARCH_DB_*). Ist dort kein Passwort gesetzt oder die direkte
# Verbindung fehlgeschlagen, wird lokal per `sudo -u postgres psql`
# ausgefuehrt (gleicher Weg wie in web/app.py).
set -euo pipefail
cd "$(dirname "$0")"
# Muss zu SUGGEST_PRIORITY in priorityweb/app.py passen.
SUGGEST_PRIORITY=1000000
usage() {
sed -n '2,27p' "$0" | sed 's/^# \{0,1\}//'
exit 0
}
YES=0
for arg in "$@"; do
case "$arg" in
-y|--yes) YES=1 ;;
-h|--help) usage ;;
*) echo "Unbekanntes Argument: $arg (--help fuer Nutzung)" >&2; exit 2 ;;
esac
done
# ---------------------------------------------------------------
# Zugangsdaten aus .env laden (nur JONASSEARCH_DB_*-Zeilen)
# ---------------------------------------------------------------
if [[ -f .env ]]; then
set -a
# shellcheck disable=SC1091
source <(grep -E '^JONASSEARCH_DB_[A-Z]+=' .env | tr -d '\r')
set +a
fi
DB_HOST="${JONASSEARCH_DB_HOST:-127.0.0.1}"
DB_PORT="${JONASSEARCH_DB_PORT:-25432}"
DB_NAME="${JONASSEARCH_DB_NAME:-jonassearch}"
DB_USER="${JONASSEARCH_DB_USER:-jonassearch}"
# ---------------------------------------------------------------
# psql-Wrapper: zuerst direkt mit Passwort, sonst als postgres-Superuser
# ---------------------------------------------------------------
psql_run() {
if [[ -n "${JONASSEARCH_DB_PASSWORD:-}" ]] && command -v psql >/dev/null 2>&1; then
if PGPASSWORD="${JONASSEARCH_DB_PASSWORD}" \
psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" \
-v ON_ERROR_STOP=1 "$@"; then
return 0
fi
echo "Direkte DB-Verbindung fehlgeschlagen — Fallback: sudo -u postgres psql" >&2
fi
sudo -u postgres psql -p "$DB_PORT" -d "$DB_NAME" -v ON_ERROR_STOP=1 "$@"
}
die() { echo "FEHLER: $*" >&2; exit 3; }
# ---------------------------------------------------------------
# 1) Existiert die Tabelle ueberhaupt?
# (Die App legt sie beim ersten Vorschlag selbst an.)
# ---------------------------------------------------------------
EXISTS="$(psql_run -t -A -c \
"SELECT to_regclass('public.domain_suggestions') IS NOT NULL;")" \
|| die "keine Verbindung zur DB ${DB_HOST}:${DB_PORT}/${DB_NAME}"
if [[ "$EXISTS" != "t" ]]; then
echo "Tabelle 'domain_suggestions' existiert nicht — es gibt nichts zu loeschen."
exit 0
fi
# ---------------------------------------------------------------
# 2) Zaehlen und bestaetigen lassen
# ---------------------------------------------------------------
BEFORE="$(psql_run -t -A -c "SELECT COUNT(*) FROM domain_suggestions;")" \
|| die "Konnte Anzahl der Eintraege nicht lesen."
echo "DB : ${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
echo "Eintraege : ${BEFORE}"
if [[ "$BEFORE" == "0" ]]; then
echo "Tabelle ist bereits leer — nichts zu tun."
exit 0
fi
if (( ! YES )); then
read -r -p "Wirklich ALLE ${BEFORE} Eintraege aus 'domain_suggestions' loeschen? (yes/no) " answer
if [[ "$answer" != "yes" ]]; then
echo "Abgebrochen — nichts geloescht."
exit 1
fi
fi
# ---------------------------------------------------------------
# 3) Loeschen (DELETE statt TRUNCATE: kein ACCESS EXCLUSIVE Lock,
# vertraeglich mit gleichzeitig laufenden Vorschlaegen im UI)
# ---------------------------------------------------------------
DELETED="$(psql_run -t -A -c \
"WITH d AS (DELETE FROM domain_suggestions RETURNING 1) \
SELECT COUNT(*) FROM d;")" \
|| die "DELETE fehlgeschlagen."
echo "Geloescht : ${DELETED} Eintraege (vorher: ${BEFORE})."
echo "Die Liste 'Letzte Vorschlaege' im Web-UI leert sich beim naechsten Refresh (max. 30 s)."
# ---------------------------------------------------------------
# 4) Nur Hinweis: stecken in der crawl_queue noch priorisierte Domains?
# (gleicher schneller Index-Range wie /api/queue in der App)
# ---------------------------------------------------------------
BOOSTED="$(psql_run -t -A -c \
"SELECT COUNT(*) FROM crawl_queue \
WHERE status = 'pending' AND priority >= ${SUGGEST_PRIORITY};" 2>/dev/null)" \
|| BOOSTED="?"
if [[ "$BOOSTED" != "0" ]]; then
echo "Hinweis: ${BOOSTED} priorisierte Domain(s) stecken noch in der crawl_queue"
echo " (dort bleiben sie auch nach diesem Skript vorne)."
echo " Aufheben mit:"
echo " DELETE FROM crawl_queue WHERE status = 'pending' AND priority >= ${SUGGEST_PRIORITY};"
fi