Select Bazarr providers via fzf from the live image

Drop hardcoded subtitle-provider defaults. Wire-up lists providers
from the running Bazarr container and enables only user selections
(plus OpenSubtitles.com when credentials were saved).
This commit is contained in:
soulis-1256 2026-08-12 15:08:59 +03:00
parent a72875a77a
commit 987fd0ccac
No known key found for this signature in database
6 changed files with 106 additions and 26 deletions

View file

@ -184,6 +184,7 @@ fi
# Bazarr after *arr (+ Jellyfin key when available): auto-subs for Sonarr/Radarr library
if [ -n "$RADARR_API_KEY" ] || [ -n "$SONARR_API_KEY" ]; then
run_optional configure_subtitle_providers
run_critical configure_bazarr
fi

View file

@ -640,7 +640,7 @@ echo " Subtitle language: ${subtitle_language:-en (Bazarr default)}"
if [ "${opensubtitles_enabled:-n}" = "y" ]; then
echo " OpenSubtitles.com: yes (username=${opensubtitles_username})"
else
echo " OpenSubtitles.com: no (free providers only)"
echo " OpenSubtitles.com: no (pick providers at wire-up)"
fi
echo " Timezone: $tz"
echo " Service login: $auth_username"

View file

@ -2,7 +2,7 @@
assemblrr uses [Recyclarr](https://recyclarr.dev/) to sync [TRaSH Guides](https://trash-guides.info/) quality profiles and custom formats into Radarr and Sonarr.
**Subtitles:** Bazarr is wired separately (not via Recyclarr). On first install and every `assemblrr upgrade`, assemblrr applies [TRaSH Bazarr suggested scoring](https://trash-guides.info/Bazarr/Bazarr-suggested-scoring/) (series min score 90, movies 80, auto-sync thresholds 96/86) plus free multi-provider defaults and optional OpenSubtitles.com credentials from setup.
**Subtitles:** Bazarr is wired separately (not via Recyclarr). On first install and every `assemblrr upgrade`, assemblrr applies [TRaSH Bazarr suggested scoring](https://trash-guides.info/Bazarr/Bazarr-suggested-scoring/) (series min score 90, movies 80, auto-sync thresholds 96/86). Subtitle providers are chosen interactively from the running Bazarr image (fzf multi-select; nothing enabled unless you pick it). OpenSubtitles.com is enabled only when you saved credentials during setup.
**Both resolutions are always installed** as assemblrr-named profiles (movies: **assemblrr HD Bluray + WEB** + **assemblrr UHD Bluray + WEB**; TV: **assemblrr WEB-1080p** + **assemblrr WEB-2160p**). The setup question only picks Seerr’s *default* for movie requests — the other profile stays available in the quality dropdown. Stock Radarr/Sonarr profiles (Any, HD-1080p, …) also appear there; that is normal.

View file

@ -222,10 +222,25 @@ configure_bazarr() {
os_pass=$(cat "$INSTALL_DIR/secrets/opensubtitles_password.txt" 2>/dev/null || echo "")
fi
# Default free / no-account providers (+ OS.com when creds present)
providers=(gestdown yifysubtitles tvsubtitles bsplayer embeddedsubtitles)
# Providers: user selection from live Bazarr catalog (configure_subtitle_providers).
# No hardcoded third-party defaults — same model as Prowlarr indexers.
providers=()
if [ -n "${SELECTED_SUBTITLE_PROVIDERS+x}" ] && [ "${#SELECTED_SUBTITLE_PROVIDERS[@]}" -gt 0 ]; then
providers=("${SELECTED_SUBTITLE_PROVIDERS[@]}")
fi
# User supplied OS.com credentials during setup → enable that provider
if [ -n "$os_user" ] && [ -n "$os_pass" ]; then
providers+=(opensubtitlescom)
local has_os=0
local p
for p in "${providers[@]+"${providers[@]}"}"; do
[ "$p" = "opensubtitlescom" ] && has_os=1 && break
done
if [ "$has_os" -eq 0 ]; then
providers+=(opensubtitlescom)
fi
fi
if [ "${#providers[@]}" -eq 0 ]; then
log_step "Bazarr: no subtitle providers selected (configure later in Bazarr UI)"
fi
# --- Core integrations + TRaSH-style scoring ---
@ -250,7 +265,7 @@ configure_bazarr() {
)
local p
for p in "${providers[@]}"; do
for p in "${providers[@]+"${providers[@]}"}"; do
form_args+=(-F "settings-general-enabled_providers=${p}")
done

View file

@ -1,12 +1,13 @@
#!/bin/bash
# fzf-based TUI for selections (Prowlarr indexers, Jellyfin languages)
# fzf-based TUI for selections (Prowlarr indexers, Bazarr providers, languages)
# Provides reusable fzf selection patterns for assemblrr.
# Sets SELECTED_INDEXERS array for Prowlarr.
# Sets SELECTED_INDEXERS / SELECTED_SUBTITLE_PROVIDERS arrays.
# Usage: source lib/fzf-tui.sh; configure_indexers "$api_key"
set -euo pipefail
SELECTED_INDEXERS=()
SELECTED_SUBTITLE_PROVIDERS=()
# --- TTY detection (reused across functions) ---
_fzf_has_tty() {
@ -72,12 +73,21 @@ fzf_single_select() {
fi
}
# --- Generic multi-select fzf (for indexers) ---
# --- Generic multi-select fzf ---
# Args: $1 = tab-separated list lines
# Sets SELECTED_INDEXERS array
# $2 = prompt (optional)
# $3 = header (optional)
# $4 = result array name (optional; default SELECTED_INDEXERS)
# $5 = noun for log messages (optional; default "item")
# Appends selected first-column values into the named array.
fzf_multi_select() {
local data="$1"
local prompt="${2:-Select items> }"
local header="${3:-Enter/TAB=toggle Ctrl-O=confirm Esc=skip}"
local result_var="${4:-SELECTED_INDEXERS}"
local noun="${5:-item}"
local has_tty=false
local -n _fzf_result_ref="$result_var"
_fzf_has_tty && has_tty=true
@ -86,17 +96,16 @@ fzf_multi_select() {
fi
if _fzf_can_render && $has_tty; then
# fzf TUI: multi-select with toggle+confirm
local selected
selected=$(echo "$data" | fzf \
--multi \
--prompt="Select indexers> " \
--prompt="$prompt" \
--delimiter='\t' \
--with-nth=1..2 \
--bind='enter:toggle' \
--bind='tab:toggle' \
--bind='ctrl-o:accept' \
--header='Enter/TAB=toggle Ctrl-O=confirm Esc=skip [P]=private' \
--header="$header" \
--height=80% \
--layout=reverse \
--border \
@ -104,20 +113,19 @@ fzf_multi_select() {
if [ -n "$selected" ]; then
while IFS= read -r idx; do
[ -n "$idx" ] && SELECTED_INDEXERS+=("$idx")
[ -n "$idx" ] && _fzf_result_ref+=("$idx")
done <<< "$selected"
echo "Selected ${#SELECTED_INDEXERS[@]} indexer(s): $(IFS=,; echo "${SELECTED_INDEXERS[*]}")" >&2
echo "Selected ${#_fzf_result_ref[@]} ${noun}(s): $(IFS=,; echo "${_fzf_result_ref[*]}")" >&2
else
echo "No indexers selected." >&2
echo "No ${noun}s selected." >&2
fi
else
# No TTY or no fzf — list options and prompt
echo "No interactive terminal available — listing available indexers." >&2
echo "$data" | cut -f1 | head -20 | sed 's/^/ /' >&2
echo "Enter indexer names separated by spaces (or blank to skip):" >&2
echo "No interactive terminal available — listing available ${noun}s." >&2
echo "$data" | cut -f1 | head -40 | sed 's/^/ /' >&2
echo "Enter ${noun} names separated by spaces (or blank to skip):" >&2
read -r input_line || true
for idx in $input_line; do
SELECTED_INDEXERS+=("$idx")
_fzf_result_ref+=("$idx")
done
fi
}
@ -147,9 +155,65 @@ configure_indexers() {
if [ -n "$indexer_data" ] && echo "$indexer_data" | jq -e 'type == "array"' >/dev/null 2>&1; then
local formatted
formatted=$(echo "$indexer_data" | jq -r 'sort_by(.name | ascii_downcase)[] | "\(.name)\t\(if .enable then "" else "[P]" end)\t\(.description // "" | gsub("\n"; " ") | .[0:120])"' 2>/dev/null)
fzf_multi_select "$formatted"
fzf_multi_select "$formatted" \
"Select indexers> " \
"Enter/TAB=toggle Ctrl-O=confirm Esc=skip [P]=private" \
SELECTED_INDEXERS \
"indexer"
else
echo "Prowlarr is not responding — skipping indexer selection." >&2
echo "You can add indexers later via the Prowlarr web UI." >&2
fi
}
# List subtitle provider keys from the running Bazarr container (Bazarr's catalog, not ours).
# Skips internal modules only (mixins/utils/helpers), not branded providers.
_list_bazarr_providers_from_container() {
local dirs=(
/app/bazarr/bin/custom_libs/subliminal_patch/providers
/app/bazarr/custom_libs/subliminal_patch/providers
)
local d names=""
if ! command -v docker &>/dev/null; then
return 1
fi
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -qx 'bazarr'; then
return 1
fi
for d in "${dirs[@]}"; do
names=$(docker exec bazarr sh -c \
"ls -1 '${d}'/*.py 2>/dev/null | xargs -n1 basename 2>/dev/null" 2>/dev/null || true)
if [ -n "$names" ]; then
echo "$names" | sed 's/\.py$//' | grep -vE '^(mixins|utils|avistaz_network|_.*)$' | sort -u
return 0
fi
done
return 1
}
# --- Bazarr subtitle provider selection (live from container, same idea as Prowlarr) ---
configure_subtitle_providers() {
SELECTED_SUBTITLE_PROVIDERS=()
echo >&2
log_warning "Time to pick subtitle providers for Bazarr." >&2
echo "List comes from the running Bazarr image. Nothing is enabled unless you select it." >&2
echo "OpenSubtitles.com is added automatically when you saved credentials during setup." >&2
local names formatted
if ! names=$(_list_bazarr_providers_from_container); then
echo "Bazarr container not available — skipping provider selection." >&2
echo "You can add providers later via the Bazarr web UI." >&2
return 0
fi
if [ -z "$names" ]; then
echo "No providers found in Bazarr image — skipping." >&2
return 0
fi
formatted=$(echo "$names" | awk '{print $1 "\t"}')
fzf_multi_select "$formatted" \
"Select subtitle providers> " \
"Enter/TAB=toggle Ctrl-O=confirm Esc=skip (enable none)" \
SELECTED_SUBTITLE_PROVIDERS \
"provider"
}

View file

@ -116,21 +116,21 @@ configure_opensubtitles() {
opensubtitles_password=""
if [ "${SETUP_MODE:-}" = "express" ]; then
log_success "OpenSubtitles.com: skipped (express mode — free providers only)"
log_success "OpenSubtitles.com: skipped (express mode — pick providers at wire-up)"
export opensubtitles_enabled opensubtitles_username opensubtitles_password
return 0
fi
echo
echo
log_info "Bazarr can download subtitles without an account (multiple free providers)."
log_info "Optional: OpenSubtitles.com improves coverage (free account: https://www.opensubtitles.com/)."
log_info "Subtitle providers are chosen later (fzf from the Bazarr image), same idea as Prowlarr indexers."
log_info "Optional: OpenSubtitles.com account for that provider (https://www.opensubtitles.com/)."
read -p "Do you have OpenSubtitles.com credentials? (y/N) [Default = n]: " opensubtitles_enabled
opensubtitles_enabled=${opensubtitles_enabled:-n}
if [ "${opensubtitles_enabled,,}" != "y" ]; then
opensubtitles_enabled="n"
log_success "OpenSubtitles.com: not configured (free providers only)"
log_success "OpenSubtitles.com: not configured (enable later via provider picker or Bazarr UI)"
export opensubtitles_enabled opensubtitles_username opensubtitles_password
return 0
fi