#!/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