replace category/engine text prompts with whiptail checklists

For both setup scripts and configure-searxng-safesearch.sh:
- Five whiptail checklist menus: Web · Images · Videos · News · Science
- Pre-populated ON/OFF based on the chosen safe-search level:
    none     → all engines ON
    moderate/strict → no-safe-search engines (mojeek, yandex, baidu, naver,
                      invidious, piped, peertube, sepiasearch, flickr,
                      imgur, deviantart, dailymotion, vimeo) default OFF
- User can toggle any engine independently before confirming
- ESC on any menu restores defaults for that category (keeps them unchanged)
- If user re-enables an auto-disabled engine, --enable-engines is passed
  to configure script to override the auto-disable
- Text fallback for non-interactive/headless installs
- Summary shows count of disabled engines instead of raw list

https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
Claude
2026-03-21 05:01:50 +00:00
parent 9bcef89719
commit e6eaec4bd4
2 changed files with 262 additions and 25 deletions
+135 -14
View File
@@ -493,11 +493,11 @@ if $INSTALL_AI; then
[[ "${DO_PULL,,}" != "n" ]] && PULL_MODELS=true [[ "${DO_PULL,,}" != "n" ]] && PULL_MODELS=true
fi fi
# ── Q6: SearXNG safe-search ─────────────────────────────────────────────────── # ── Q6: SearXNG safe-search & engine selection ────────────────────────────────
SEARXNG_SAFE_LEVEL="none" SEARXNG_SAFE_LEVEL="none"
SEARXNG_SAFE_INT=0 SEARXNG_SAFE_INT=0
SEARXNG_DISABLE_CATS=""
SEARXNG_DISABLE_ENGINES="" SEARXNG_DISABLE_ENGINES=""
SEARXNG_ENABLE_ENGINES=""
if $INSTALL_AI && $SVC_SEARXNG; then if $INSTALL_AI && $SVC_SEARXNG; then
echo "" echo ""
@@ -513,15 +513,134 @@ if $INSTALL_AI && $SVC_SEARXNG; then
*) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;; *) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;;
esac esac
echo "" # Default ON/OFF for an engine given the chosen safe-search level
echo " Disable search categories? (Enter to keep all)" _sxst() {
echo " Options: videos images news science social" [[ "$SEARXNG_SAFE_LEVEL" == "none" ]] && echo ON && return
read -rp " Categories (space-separated, Enter to skip): " SEARXNG_DISABLE_CATS case "$1" in
mojeek|yandex|baidu|naver|invidious|piped|peertube|sepiasearch|\
dailymotion|vimeo|imgur|deviantart|flickr) echo OFF ;;
*) echo ON ;;
esac
}
echo "" # Whiptail checklist — prints selected engine names (one per line).
echo " Disable specific engines? (Enter to keep defaults)" # ESC returns the engines that were pre-checked ON (keeps defaults unchanged).
echo " Web: google bing duckduckgo brave startpage qwant yahoo" # Args: "Title" name "Desc" ON|OFF [name "Desc" ON|OFF ...]
read -rp " Engines (space-separated, Enter to skip): " SEARXNG_DISABLE_ENGINES _sxmenu() {
local _t="$1"; shift
local -a _n=() _s=() _a=(); local _i=1
while [[ $# -ge 3 ]]; do
_n+=("$1"); _s+=("$3")
_a+=("$_i" "$(printf '%-22s %s' "$1" "$2")" "$3")
_i=$(( _i + 1 )); shift 3
done
local _h=$(( ${#_n[@]} + 9 > 24 ? 24 : ${#_n[@]} + 9 ))
local _lh=$(( ${#_n[@]} < 14 ? ${#_n[@]} : 14 ))
local _o _j
if ! _o=$(whiptail --backtitle "SearXNG — $SEARXNG_SAFE_LEVEL" \
--title "$_t" --checklist \
"SPACE = toggle ENTER = confirm ESC = use defaults" \
"$_h" 72 "$_lh" "${_a[@]}" 3>&1 1>&2 2>&3 2>/dev/null); then
for _j in "${!_n[@]}"; do
[[ "${_s[$_j]}" == "ON" ]] && printf '%s\n' "${_n[$_j]}"
done
return
fi
for _id in $_o; do _id="${_id//\"/}"; printf '%s\n' "${_n[$(( _id-1 ))]}"; done
}
# Engines auto-disabled by configure script for moderate/strict.
# If user re-enables one in the menu we pass --enable-engines to override.
_SX_AUTOFF=(mojeek yandex baidu naver invidious piped peertube sepiasearch)
if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
_SX_W=$(_sxmenu "Web Search Engines" \
"google" "Google" ON \
"bing" "Microsoft Bing" ON \
"duckduckgo" "DuckDuckGo" ON \
"brave" "Brave Search" ON \
"startpage" "Startpage (Google proxy)" ON \
"qwant" "Qwant" ON \
"yahoo" "Yahoo" ON \
"ecosia" "Ecosia" ON \
"mojeek" "Mojeek [no safe-search]" "$(_sxst mojeek)" \
"yandex" "Yandex [unreliable filter]" "$(_sxst yandex)" \
"baidu" "Baidu [no safe-search]" "$(_sxst baidu)" \
"naver" "Naver [no safe-search]" "$(_sxst naver)")
_SX_I=$(_sxmenu "Image Search Engines" \
"google images" "Google Images" ON \
"bing images" "Bing Images" ON \
"duckduckgo images" "DuckDuckGo Images" ON \
"brave images" "Brave Images" ON \
"qwant images" "Qwant Images" ON \
"openverse" "Openverse (open license)" ON \
"unsplash" "Unsplash (stock photos)" ON \
"flickr" "Flickr [no safe-search]" "$(_sxst flickr)" \
"imgur" "Imgur [no safe-search]" "$(_sxst imgur)" \
"deviantart" "DeviantArt [no filter]" "$(_sxst deviantart)")
_SX_V=$(_sxmenu "Video Search Engines" \
"youtube" "YouTube (via Google)" ON \
"bing videos" "Bing Videos" ON \
"duckduckgo videos" "DuckDuckGo Videos" ON \
"google videos" "Google Videos" ON \
"invidious" "Invidious [no filter]" "$(_sxst invidious)" \
"piped" "Piped [no filter]" "$(_sxst piped)" \
"peertube" "PeerTube [no filter]" "$(_sxst peertube)" \
"sepiasearch" "SepiaSearch [no filter]" "$(_sxst sepiasearch)" \
"dailymotion" "Dailymotion [no filter]" "$(_sxst dailymotion)" \
"vimeo" "Vimeo [no filter]" "$(_sxst vimeo)")
_SX_N=$(_sxmenu "News Search Engines" \
"google news" "Google News" ON \
"bing news" "Bing News" ON \
"duckduckgo news" "DuckDuckGo News" ON \
"brave news" "Brave News" ON \
"qwant news" "Qwant News" ON)
_SX_S=$(_sxmenu "Science / Academic" \
"arxiv" "arXiv (preprints)" ON \
"semantic scholar" "Semantic Scholar" ON \
"pubmed" "PubMed (medical)" ON \
"crossref" "Crossref (DOI/papers)" ON \
"base" "BASE (open access)" ON)
_SX_ALL=(
"google" "bing" "duckduckgo" "brave" "startpage" "qwant" "yahoo" "ecosia"
"mojeek" "yandex" "baidu" "naver"
"google images" "bing images" "duckduckgo images" "brave images" "qwant images"
"openverse" "unsplash" "flickr" "imgur" "deviantart"
"youtube" "bing videos" "duckduckgo videos" "google videos"
"invidious" "piped" "peertube" "sepiasearch" "dailymotion" "vimeo"
"google news" "bing news" "duckduckgo news" "brave news" "qwant news"
"arxiv" "semantic scholar" "pubmed" "crossref" "base"
)
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_S")
for _e in "${_SX_ALL[@]}"; do
if printf '%s\n' "$_SX_SEL" | grep -qxF "$_e"; then
# Selected — if auto-disabled by level, pass --enable-engines to override
for _ao in "${_SX_AUTOFF[@]}"; do
if [[ "$_e" == "$_ao" ]]; then
SEARXNG_ENABLE_ENGINES+="${SEARXNG_ENABLE_ENGINES:+,}${_e}"
break
fi
done
else
SEARXNG_DISABLE_ENGINES+="${SEARXNG_DISABLE_ENGINES:+,}${_e}"
fi
done
else
# Fallback: no whiptail / non-interactive terminal
echo ""
echo " (whiptail not available — text entry)"
echo " Web: google bing duckduckgo brave startpage qwant yahoo"
echo " Imgs: google_images bing_images duckduckgo_images flickr imgur"
echo " Vids: youtube invidious piped peertube dailymotion vimeo"
read -rp " Engines to disable (space-separated, Enter for defaults): " _ENGS
SEARXNG_DISABLE_ENGINES="${_ENGS// /,}"
fi
fi fi
# ── Summary ─────────────────────────────────────────────────────────────────── # ── Summary ───────────────────────────────────────────────────────────────────
@@ -554,8 +673,10 @@ fi
$SVC_KIWIX && echo " ✓ Kiwix ZIMs → $KIWIX_DIR" $SVC_KIWIX && echo " ✓ Kiwix ZIMs → $KIWIX_DIR"
if $INSTALL_AI && $SVC_SEARXNG; then if $INSTALL_AI && $SVC_SEARXNG; then
_sx="safe_search: $SEARXNG_SAFE_LEVEL" _sx="safe_search: $SEARXNG_SAFE_LEVEL"
[[ -n "$SEARXNG_DISABLE_CATS" ]] && _sx+=" | disabled cats: $SEARXNG_DISABLE_CATS" if [[ -n "$SEARXNG_DISABLE_ENGINES" ]]; then
[[ -n "$SEARXNG_DISABLE_ENGINES" ]] && _sx+=" | disabled engines: $SEARXNG_DISABLE_ENGINES" _ndis=$(tr ',' '\n' <<< "$SEARXNG_DISABLE_ENGINES" | grep -c .)
_sx+=" | ${_ndis} engines disabled"
fi
echo " ✓ SearXNG → $_sx" echo " ✓ SearXNG → $_sx"
fi fi
$PULL_MODELS && echo " ✓ Pull models : $EMBED_MODEL + $FAST_MODEL + $CHAT_MODEL + $CODE_MODEL${REASON_MODEL:+ + $REASON_MODEL}" $PULL_MODELS && echo " ✓ Pull models : $EMBED_MODEL + $FAST_MODEL + $CHAT_MODEL + $CODE_MODEL${REASON_MODEL:+ + $REASON_MODEL}"
@@ -716,8 +837,8 @@ section "SearXNG Config"
# ============================================================================= # =============================================================================
mkdir -p "$BASE/searxng" mkdir -p "$BASE/searxng"
_SXARGS=("$SEARXNG_SAFE_LEVEL") _SXARGS=("$SEARXNG_SAFE_LEVEL")
[[ -n "$SEARXNG_DISABLE_CATS" ]] && _SXARGS+=(--disable-categories "${SEARXNG_DISABLE_CATS// /,}") [[ -n "$SEARXNG_DISABLE_ENGINES" ]] && _SXARGS+=(--disable-engines "$SEARXNG_DISABLE_ENGINES")
[[ -n "$SEARXNG_DISABLE_ENGINES" ]] && _SXARGS+=(--disable-engines "${SEARXNG_DISABLE_ENGINES// /,}") [[ -n "$SEARXNG_ENABLE_ENGINES" ]] && _SXARGS+=(--enable-engines "$SEARXNG_ENABLE_ENGINES")
BASE="$BASE" bash "$SCRIPT_DIR/configure-searxng-safesearch.sh" "${_SXARGS[@]}" BASE="$BASE" bash "$SCRIPT_DIR/configure-searxng-safesearch.sh" "${_SXARGS[@]}"
fi # INSTALL_AI && SVC_SEARXNG fi # INSTALL_AI && SVC_SEARXNG
+127 -11
View File
@@ -44,7 +44,9 @@ info "Base : $BASE"
info "IP : $LOCAL_IP" info "IP : $LOCAL_IP"
info "GPU : ${VRAM_GB}GB VRAM → $TIER" info "GPU : ${VRAM_GB}GB VRAM → $TIER"
# ── SearXNG safe-search ─────────────────────────────────────────────────────── # ── SearXNG safe-search & engine selection ────────────────────────────────────
SEARXNG_DISABLE_ENGINES=""
SEARXNG_ENABLE_ENGINES=""
echo "" echo ""
echo " SearXNG safe-search level:" echo " SearXNG safe-search level:"
echo " 0) None — all results, no filtering (default)" echo " 0) None — all results, no filtering (default)"
@@ -58,15 +60,129 @@ case "${_SAFE_PICK:-0}" in
*) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;; *) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;;
esac esac
echo "" # Default ON/OFF for an engine given the chosen safe-search level
echo " Disable search categories? (Enter to keep all)" _sxst() {
echo " Options: videos images news science social" [[ "$SEARXNG_SAFE_LEVEL" == "none" ]] && echo ON && return
read -rp " Categories (space-separated, Enter to skip): " SEARXNG_DISABLE_CATS case "$1" in
mojeek|yandex|baidu|naver|invidious|piped|peertube|sepiasearch|\
dailymotion|vimeo|imgur|deviantart|flickr) echo OFF ;;
*) echo ON ;;
esac
}
echo "" # Whiptail checklist — prints selected engine names (one per line).
echo " Disable specific engines? (Enter to keep defaults)" # ESC returns the engines that were pre-checked ON (keeps defaults unchanged).
echo " Web: google bing duckduckgo brave startpage qwant yahoo" _sxmenu() {
read -rp " Engines (space-separated, Enter to skip): " SEARXNG_DISABLE_ENGINES local _t="$1"; shift
local -a _n=() _s=() _a=(); local _i=1
while [[ $# -ge 3 ]]; do
_n+=("$1"); _s+=("$3")
_a+=("$_i" "$(printf '%-22s %s' "$1" "$2")" "$3")
_i=$(( _i + 1 )); shift 3
done
local _h=$(( ${#_n[@]} + 9 > 24 ? 24 : ${#_n[@]} + 9 ))
local _lh=$(( ${#_n[@]} < 14 ? ${#_n[@]} : 14 ))
local _o _j
if ! _o=$(whiptail --backtitle "SearXNG — $SEARXNG_SAFE_LEVEL" \
--title "$_t" --checklist \
"SPACE = toggle ENTER = confirm ESC = use defaults" \
"$_h" 72 "$_lh" "${_a[@]}" 3>&1 1>&2 2>&3 2>/dev/null); then
for _j in "${!_n[@]}"; do
[[ "${_s[$_j]}" == "ON" ]] && printf '%s\n' "${_n[$_j]}"
done
return
fi
for _id in $_o; do _id="${_id//\"/}"; printf '%s\n' "${_n[$(( _id-1 ))]}"; done
}
_SX_AUTOFF=(mojeek yandex baidu naver invidious piped peertube sepiasearch)
if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
_SX_W=$(_sxmenu "Web Search Engines" \
"google" "Google" ON \
"bing" "Microsoft Bing" ON \
"duckduckgo" "DuckDuckGo" ON \
"brave" "Brave Search" ON \
"startpage" "Startpage (Google proxy)" ON \
"qwant" "Qwant" ON \
"yahoo" "Yahoo" ON \
"ecosia" "Ecosia" ON \
"mojeek" "Mojeek [no safe-search]" "$(_sxst mojeek)" \
"yandex" "Yandex [unreliable filter]" "$(_sxst yandex)" \
"baidu" "Baidu [no safe-search]" "$(_sxst baidu)" \
"naver" "Naver [no safe-search]" "$(_sxst naver)")
_SX_I=$(_sxmenu "Image Search Engines" \
"google images" "Google Images" ON \
"bing images" "Bing Images" ON \
"duckduckgo images" "DuckDuckGo Images" ON \
"brave images" "Brave Images" ON \
"qwant images" "Qwant Images" ON \
"openverse" "Openverse (open license)" ON \
"unsplash" "Unsplash (stock photos)" ON \
"flickr" "Flickr [no safe-search]" "$(_sxst flickr)" \
"imgur" "Imgur [no safe-search]" "$(_sxst imgur)" \
"deviantart" "DeviantArt [no filter]" "$(_sxst deviantart)")
_SX_V=$(_sxmenu "Video Search Engines" \
"youtube" "YouTube (via Google)" ON \
"bing videos" "Bing Videos" ON \
"duckduckgo videos" "DuckDuckGo Videos" ON \
"google videos" "Google Videos" ON \
"invidious" "Invidious [no filter]" "$(_sxst invidious)" \
"piped" "Piped [no filter]" "$(_sxst piped)" \
"peertube" "PeerTube [no filter]" "$(_sxst peertube)" \
"sepiasearch" "SepiaSearch [no filter]" "$(_sxst sepiasearch)" \
"dailymotion" "Dailymotion [no filter]" "$(_sxst dailymotion)" \
"vimeo" "Vimeo [no filter]" "$(_sxst vimeo)")
_SX_N=$(_sxmenu "News Search Engines" \
"google news" "Google News" ON \
"bing news" "Bing News" ON \
"duckduckgo news" "DuckDuckGo News" ON \
"brave news" "Brave News" ON \
"qwant news" "Qwant News" ON)
_SX_S=$(_sxmenu "Science / Academic" \
"arxiv" "arXiv (preprints)" ON \
"semantic scholar" "Semantic Scholar" ON \
"pubmed" "PubMed (medical)" ON \
"crossref" "Crossref (DOI/papers)" ON \
"base" "BASE (open access)" ON)
_SX_ALL=(
"google" "bing" "duckduckgo" "brave" "startpage" "qwant" "yahoo" "ecosia"
"mojeek" "yandex" "baidu" "naver"
"google images" "bing images" "duckduckgo images" "brave images" "qwant images"
"openverse" "unsplash" "flickr" "imgur" "deviantart"
"youtube" "bing videos" "duckduckgo videos" "google videos"
"invidious" "piped" "peertube" "sepiasearch" "dailymotion" "vimeo"
"google news" "bing news" "duckduckgo news" "brave news" "qwant news"
"arxiv" "semantic scholar" "pubmed" "crossref" "base"
)
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_S")
for _e in "${_SX_ALL[@]}"; do
if printf '%s\n' "$_SX_SEL" | grep -qxF "$_e"; then
for _ao in "${_SX_AUTOFF[@]}"; do
if [[ "$_e" == "$_ao" ]]; then
SEARXNG_ENABLE_ENGINES+="${SEARXNG_ENABLE_ENGINES:+,}${_e}"
break
fi
done
else
SEARXNG_DISABLE_ENGINES+="${SEARXNG_DISABLE_ENGINES:+,}${_e}"
fi
done
else
echo ""
echo " (whiptail not available — text entry)"
echo " Web: google bing duckduckgo brave startpage qwant yahoo"
echo " Imgs: google_images bing_images duckduckgo_images flickr imgur"
echo " Vids: youtube invidious piped peertube dailymotion vimeo"
read -rp " Engines to disable (space-separated, Enter for defaults): " _ENGS
SEARXNG_DISABLE_ENGINES="${_ENGS// /,}"
fi
echo "" echo ""
write_if_new() { write_if_new() {
@@ -509,8 +625,8 @@ section "SearXNG Config"
# ============================================================================= # =============================================================================
mkdir -p "$BASE/searxng" mkdir -p "$BASE/searxng"
_SXARGS=("$SEARXNG_SAFE_LEVEL") _SXARGS=("$SEARXNG_SAFE_LEVEL")
[[ -n "$SEARXNG_DISABLE_CATS" ]] && _SXARGS+=(--disable-categories "${SEARXNG_DISABLE_CATS// /,}") [[ -n "$SEARXNG_DISABLE_ENGINES" ]] && _SXARGS+=(--disable-engines "$SEARXNG_DISABLE_ENGINES")
[[ -n "$SEARXNG_DISABLE_ENGINES" ]] && _SXARGS+=(--disable-engines "${SEARXNG_DISABLE_ENGINES// /,}") [[ -n "$SEARXNG_ENABLE_ENGINES" ]] && _SXARGS+=(--enable-engines "$SEARXNG_ENABLE_ENGINES")
BASE="$BASE" bash "$SCRIPT_DIR/configure-searxng-safesearch.sh" "${_SXARGS[@]}" BASE="$BASE" bash "$SCRIPT_DIR/configure-searxng-safesearch.sh" "${_SXARGS[@]}"
# ============================================================================= # =============================================================================