expand engine menus to ~80 engines across 6 categories; fix permissions

configure-searxng-safesearch.sh:
- Fix "Permission denied" when Docker created settings.yml as root:
  detect unwritable file, run sudo chown before writing

Engine menus (both setup scripts):
- Web:       +presearch, yep, wiby  (15 total)
- Images:    +startpage images, mojeek images, presearch images,
              pexels, pixabay images, pinterest, flickr (moved to ON — it
              supports safe-search), wikcommons.images, artstation, adobe stock
              (19 total); removed flickr/dailymotion from no-safe-search list
- Videos:    +brave videos, qwant videos, rumble, odysee, bitchute,
              media.ccc.de, wikcommons.videos  (17 total)
- News:      +startpage news, presearch news, mojeek news, reuters,
              yahoo news, wikinews, yep news  (12 total)
- Reference: NEW — wikipedia, wikidata, wolframalpha, ask, ddg definitions,
              encyclopsearch, wikibooks, wikiquote, wikisource, wikispecies,
              wikiversity, wikivoyage  (12 total)
- Science:   unchanged (5)

_sxst() updated: removed flickr/dailymotion from OFF list; added
  vimeo, bitchute, rumble, odysee, artstation, mojeek images/news

https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
Claude
2026-03-21 05:28:23 +00:00
parent 9a329a754b
commit fc10cbf668
3 changed files with 246 additions and 108 deletions
+8 -2
View File
@@ -55,8 +55,14 @@ done
SETTINGS="$BASE/searxng/settings.yml"
COMPOSE="$BASE/docker-compose.yml"
# Ensure settings directory exists
mkdir -p "$(dirname "$SETTINGS")"
# Ensure settings directory exists (fix ownership if Docker created it as root)
mkdir -p "$(dirname "$SETTINGS")" 2>/dev/null || \
sudo mkdir -p "$(dirname "$SETTINGS")"
if [[ -e "$SETTINGS" ]] && [[ ! -w "$SETTINGS" ]]; then
warn "settings.yml not writable — fixing ownership"
sudo chown "$(id -u):$(id -g)" "$SETTINGS" || \
die "Cannot write to $SETTINGS — run: sudo chown $USER $SETTINGS"
fi
# ── Level → integer ───────────────────────────────────────────────────────────
case "$LEVEL" in
+89 -23
View File
@@ -587,12 +587,16 @@ if $INSTALL_AI && $SVC_SEARXNG; then
*) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;;
esac
# Default ON/OFF for an engine given the chosen safe-search level
# Default ON/OFF for an engine given the chosen safe-search level.
# Engines without safe-search support default OFF for moderate/strict.
_sxst() {
[[ "$SEARXNG_SAFE_LEVEL" == "none" ]] && echo ON && return
case "$1" in
mojeek|yandex|baidu|naver|invidious|piped|peertube|sepiasearch|\
dailymotion|vimeo|imgur|deviantart|flickr) echo OFF ;;
mojeek|"mojeek images"|"mojeek news"|\
yandex|baidu|naver|\
invidious|piped|peertube|sepiasearch|\
vimeo|bitchute|rumble|odysee|\
imgur|deviantart|artstation) echo OFF ;;
*) echo ON ;;
esac
}
@@ -605,7 +609,7 @@ if $INSTALL_AI && $SVC_SEARXNG; then
local -a _n=() _s=() _a=(); local _i=1
while [[ $# -ge 3 ]]; do
_n+=("$1"); _s+=("$3")
_a+=("$_i" "$(printf '%-22s %s' "$1" "$2")" "$3")
_a+=("$_i" "$(printf '%-26s %s' "$1" "$2")" "$3")
_i=$(( _i + 1 )); shift 3
done
local _h=$(( ${#_n[@]} + 9 > 24 ? 24 : ${#_n[@]} + 9 ))
@@ -614,7 +618,7 @@ if $INSTALL_AI && $SVC_SEARXNG; then
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
"$_h" 76 "$_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
@@ -628,6 +632,7 @@ if $INSTALL_AI && $SVC_SEARXNG; then
_SX_AUTOFF=(mojeek yandex baidu naver invidious piped peertube sepiasearch)
if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
# ── Web search ─────────────────────────────────────────────────────────
_SX_W=$(_sxmenu "Web Search Engines" \
"google" "Google" ON \
"bing" "Microsoft Bing" ON \
@@ -637,42 +642,87 @@ if $INSTALL_AI && $SVC_SEARXNG; then
"qwant" "Qwant" ON \
"yahoo" "Yahoo" ON \
"ecosia" "Ecosia" ON \
"presearch" "Presearch" ON \
"yep" "Yep" ON \
"wiby" "Wiby (classic/indie web)" 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)")
"naver" "Naver (Korean) [no safe-search]" "$(_sxst naver)")
# ── Images ─────────────────────────────────────────────────────────────
_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 \
"startpage images" "Startpage Images" ON \
"mojeek images" "Mojeek Images [no safe-search]" "$(_sxst 'mojeek images')" \
"presearch images" "Presearch 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)")
"pexels" "Pexels (stock photos)" ON \
"pixabay images" "Pixabay Images" ON \
"pinterest" "Pinterest" ON \
"flickr" "Flickr" ON \
"wikcommons.images" "Wikimedia Commons Images" ON \
"imgur" "Imgur [adult content]" "$(_sxst imgur)" \
"deviantart" "DeviantArt [adult content]" "$(_sxst deviantart)" \
"artstation" "ArtStation [adult content]" "$(_sxst artstation)" \
"adobe stock" "Adobe Stock" ON)
# ── Videos ─────────────────────────────────────────────────────────────
_SX_V=$(_sxmenu "Video Search Engines" \
"youtube" "YouTube (via Google)" ON \
"youtube" "YouTube" ON \
"bing videos" "Bing Videos" ON \
"brave videos" "Brave 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)")
"qwant videos" "Qwant Videos" ON \
"dailymotion" "Dailymotion" ON \
"media.ccc.de" "media.ccc.de (tech talks)" ON \
"wikcommons.videos" "Wikimedia Commons Videos" ON \
"vimeo" "Vimeo [no safe-search]" "$(_sxst vimeo)" \
"odysee" "Odysee [no safe-search]" "$(_sxst odysee)" \
"rumble" "Rumble [no safe-search]" "$(_sxst rumble)" \
"bitchute" "BitChute [no safe-search]" "$(_sxst bitchute)" \
"invidious" "Invidious (YT) [no safe-search]" "$(_sxst invidious)" \
"piped" "Piped (YT) [no safe-search]" "$(_sxst piped)" \
"peertube" "PeerTube [no safe-search]" "$(_sxst peertube)" \
"sepiasearch" "SepiaSearch [no safe-search]" "$(_sxst sepiasearch)")
# ── News ───────────────────────────────────────────────────────────────
_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)
"qwant news" "Qwant News" ON \
"startpage news" "Startpage News" ON \
"presearch news" "Presearch News" ON \
"mojeek news" "Mojeek News [no safe-search]" "$(_sxst 'mojeek news')" \
"reuters" "Reuters" ON \
"yahoo news" "Yahoo News" ON \
"wikinews" "WikiNews" ON \
"yep news" "Yep News" ON)
# ── Reference & Knowledge ──────────────────────────────────────────────
_SX_R=$(_sxmenu "Reference & Knowledge" \
"wikipedia" "Wikipedia" ON \
"wikidata" "Wikidata" ON \
"wolframalpha" "Wolfram|Alpha" ON \
"ask" "Ask.com" ON \
"ddg definitions" "DuckDuckGo Definitions" ON \
"encyclopsearch" "Encyclopsearch" ON \
"wikibooks" "Wikibooks" ON \
"wikiquote" "Wikiquote" ON \
"wikisource" "Wikisource" ON \
"wikispecies" "Wikispecies" ON \
"wikiversity" "Wikiversity" ON \
"wikivoyage" "Wikivoyage" ON)
# ── Science ────────────────────────────────────────────────────────────
_SX_S=$(_sxmenu "Science / Academic" \
"arxiv" "arXiv (preprints)" ON \
"semantic scholar" "Semantic Scholar" ON \
@@ -681,16 +731,31 @@ if $INSTALL_AI && $SVC_SEARXNG; then
"base" "BASE (open access)" ON)
_SX_ALL=(
# Web
"google" "bing" "duckduckgo" "brave" "startpage" "qwant" "yahoo" "ecosia"
"presearch" "yep" "wiby"
"mojeek" "yandex" "baidu" "naver"
# Images
"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"
"startpage images" "mojeek images" "presearch images"
"openverse" "unsplash" "pexels" "pixabay images" "pinterest" "flickr"
"wikcommons.images" "imgur" "deviantart" "artstation" "adobe stock"
# Videos
"youtube" "bing videos" "brave videos" "duckduckgo videos" "google videos" "qwant videos"
"dailymotion" "media.ccc.de" "wikcommons.videos"
"vimeo" "odysee" "rumble" "bitchute"
"invidious" "piped" "peertube" "sepiasearch"
# News
"google news" "bing news" "duckduckgo news" "brave news" "qwant news"
"startpage news" "presearch news" "mojeek news"
"reuters" "yahoo news" "wikinews" "yep news"
# Reference
"wikipedia" "wikidata" "wolframalpha" "ask" "ddg definitions" "encyclopsearch"
"wikibooks" "wikiquote" "wikisource" "wikispecies" "wikiversity" "wikivoyage"
# Science
"arxiv" "semantic scholar" "pubmed" "crossref" "base"
)
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_S")
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_R" "$_SX_S")
for _e in "${_SX_ALL[@]}"; do
if printf '%s\n' "$_SX_SEL" | grep -qxF "$_e"; then
@@ -709,9 +774,10 @@ if $INSTALL_AI && $SVC_SEARXNG; then
# Fallback: no whiptail / non-interactive terminal
echo ""
echo " (whiptail not available — text entry)"
echo " Web: google bing duckduckgo brave startpage qwant yahoo"
echo " Web: google bing duckduckgo brave startpage qwant yahoo presearch"
echo " Imgs: google_images bing_images duckduckgo_images flickr imgur"
echo " Vids: youtube invidious piped peertube dailymotion vimeo"
echo " Vids: youtube dailymotion vimeo rumble odysee bitchute"
echo " News: google_news bing_news reuters yahoo_news wikinews"
read -rp " Engines to disable (space-separated, Enter for defaults): " _ENGS
SEARXNG_DISABLE_ENGINES="${_ENGS// /,}"
fi
+89 -23
View File
@@ -60,12 +60,16 @@ case "${_SAFE_PICK:-0}" in
*) SEARXNG_SAFE_LEVEL="none"; SEARXNG_SAFE_INT=0 ;;
esac
# Default ON/OFF for an engine given the chosen safe-search level
# Default ON/OFF for an engine given the chosen safe-search level.
# Engines without safe-search support default OFF for moderate/strict.
_sxst() {
[[ "$SEARXNG_SAFE_LEVEL" == "none" ]] && echo ON && return
case "$1" in
mojeek|yandex|baidu|naver|invidious|piped|peertube|sepiasearch|\
dailymotion|vimeo|imgur|deviantart|flickr) echo OFF ;;
mojeek|"mojeek images"|"mojeek news"|\
yandex|baidu|naver|\
invidious|piped|peertube|sepiasearch|\
vimeo|bitchute|rumble|odysee|\
imgur|deviantart|artstation) echo OFF ;;
*) echo ON ;;
esac
}
@@ -77,7 +81,7 @@ _sxmenu() {
local -a _n=() _s=() _a=(); local _i=1
while [[ $# -ge 3 ]]; do
_n+=("$1"); _s+=("$3")
_a+=("$_i" "$(printf '%-22s %s' "$1" "$2")" "$3")
_a+=("$_i" "$(printf '%-26s %s' "$1" "$2")" "$3")
_i=$(( _i + 1 )); shift 3
done
local _h=$(( ${#_n[@]} + 9 > 24 ? 24 : ${#_n[@]} + 9 ))
@@ -86,7 +90,7 @@ _sxmenu() {
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
"$_h" 76 "$_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
@@ -98,6 +102,7 @@ _sxmenu() {
_SX_AUTOFF=(mojeek yandex baidu naver invidious piped peertube sepiasearch)
if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
# ── Web search ─────────────────────────────────────────────────────────────
_SX_W=$(_sxmenu "Web Search Engines" \
"google" "Google" ON \
"bing" "Microsoft Bing" ON \
@@ -107,42 +112,87 @@ if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
"qwant" "Qwant" ON \
"yahoo" "Yahoo" ON \
"ecosia" "Ecosia" ON \
"presearch" "Presearch" ON \
"yep" "Yep" ON \
"wiby" "Wiby (classic/indie web)" 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)")
"naver" "Naver (Korean) [no safe-search]" "$(_sxst naver)")
# ── Images ─────────────────────────────────────────────────────────────────
_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 \
"startpage images" "Startpage Images" ON \
"mojeek images" "Mojeek Images [no safe-search]" "$(_sxst 'mojeek images')" \
"presearch images" "Presearch 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)")
"pexels" "Pexels (stock photos)" ON \
"pixabay images" "Pixabay Images" ON \
"pinterest" "Pinterest" ON \
"flickr" "Flickr" ON \
"wikcommons.images" "Wikimedia Commons Images" ON \
"imgur" "Imgur [adult content]" "$(_sxst imgur)" \
"deviantart" "DeviantArt [adult content]" "$(_sxst deviantart)" \
"artstation" "ArtStation [adult content]" "$(_sxst artstation)" \
"adobe stock" "Adobe Stock" ON)
# ── Videos ─────────────────────────────────────────────────────────────────
_SX_V=$(_sxmenu "Video Search Engines" \
"youtube" "YouTube (via Google)" ON \
"youtube" "YouTube" ON \
"bing videos" "Bing Videos" ON \
"brave videos" "Brave 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)")
"qwant videos" "Qwant Videos" ON \
"dailymotion" "Dailymotion" ON \
"media.ccc.de" "media.ccc.de (tech talks)" ON \
"wikcommons.videos" "Wikimedia Commons Videos" ON \
"vimeo" "Vimeo [no safe-search]" "$(_sxst vimeo)" \
"odysee" "Odysee [no safe-search]" "$(_sxst odysee)" \
"rumble" "Rumble [no safe-search]" "$(_sxst rumble)" \
"bitchute" "BitChute [no safe-search]" "$(_sxst bitchute)" \
"invidious" "Invidious (YT) [no safe-search]" "$(_sxst invidious)" \
"piped" "Piped (YT) [no safe-search]" "$(_sxst piped)" \
"peertube" "PeerTube [no safe-search]" "$(_sxst peertube)" \
"sepiasearch" "SepiaSearch [no safe-search]" "$(_sxst sepiasearch)")
# ── News ───────────────────────────────────────────────────────────────────
_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)
"qwant news" "Qwant News" ON \
"startpage news" "Startpage News" ON \
"presearch news" "Presearch News" ON \
"mojeek news" "Mojeek News [no safe-search]" "$(_sxst 'mojeek news')" \
"reuters" "Reuters" ON \
"yahoo news" "Yahoo News" ON \
"wikinews" "WikiNews" ON \
"yep news" "Yep News" ON)
# ── Reference & Knowledge ──────────────────────────────────────────────────
_SX_R=$(_sxmenu "Reference & Knowledge" \
"wikipedia" "Wikipedia" ON \
"wikidata" "Wikidata" ON \
"wolframalpha" "Wolfram|Alpha" ON \
"ask" "Ask.com" ON \
"ddg definitions" "DuckDuckGo Definitions" ON \
"encyclopsearch" "Encyclopsearch" ON \
"wikibooks" "Wikibooks" ON \
"wikiquote" "Wikiquote" ON \
"wikisource" "Wikisource" ON \
"wikispecies" "Wikispecies" ON \
"wikiversity" "Wikiversity" ON \
"wikivoyage" "Wikivoyage" ON)
# ── Science ────────────────────────────────────────────────────────────────
_SX_S=$(_sxmenu "Science / Academic" \
"arxiv" "arXiv (preprints)" ON \
"semantic scholar" "Semantic Scholar" ON \
@@ -151,16 +201,31 @@ if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
"base" "BASE (open access)" ON)
_SX_ALL=(
# Web
"google" "bing" "duckduckgo" "brave" "startpage" "qwant" "yahoo" "ecosia"
"presearch" "yep" "wiby"
"mojeek" "yandex" "baidu" "naver"
# Images
"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"
"startpage images" "mojeek images" "presearch images"
"openverse" "unsplash" "pexels" "pixabay images" "pinterest" "flickr"
"wikcommons.images" "imgur" "deviantart" "artstation" "adobe stock"
# Videos
"youtube" "bing videos" "brave videos" "duckduckgo videos" "google videos" "qwant videos"
"dailymotion" "media.ccc.de" "wikcommons.videos"
"vimeo" "odysee" "rumble" "bitchute"
"invidious" "piped" "peertube" "sepiasearch"
# News
"google news" "bing news" "duckduckgo news" "brave news" "qwant news"
"startpage news" "presearch news" "mojeek news"
"reuters" "yahoo news" "wikinews" "yep news"
# Reference
"wikipedia" "wikidata" "wolframalpha" "ask" "ddg definitions" "encyclopsearch"
"wikibooks" "wikiquote" "wikisource" "wikispecies" "wikiversity" "wikivoyage"
# Science
"arxiv" "semantic scholar" "pubmed" "crossref" "base"
)
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_S")
_SX_SEL=$(printf '%s\n' "$_SX_W" "$_SX_I" "$_SX_V" "$_SX_N" "$_SX_R" "$_SX_S")
for _e in "${_SX_ALL[@]}"; do
if printf '%s\n' "$_SX_SEL" | grep -qxF "$_e"; then
@@ -177,9 +242,10 @@ if command -v whiptail &>/dev/null && [[ -t 0 ]]; then
else
echo ""
echo " (whiptail not available — text entry)"
echo " Web: google bing duckduckgo brave startpage qwant yahoo"
echo " Web: google bing duckduckgo brave startpage qwant yahoo presearch"
echo " Imgs: google_images bing_images duckduckgo_images flickr imgur"
echo " Vids: youtube invidious piped peertube dailymotion vimeo"
echo " Vids: youtube dailymotion vimeo rumble odysee bitchute"
echo " News: google_news bing_news reuters yahoo_news wikinews"
read -rp " Engines to disable (space-separated, Enter for defaults): " _ENGS
SEARXNG_DISABLE_ENGINES="${_ENGS// /,}"
fi