154 lines
4.8 KiB
Bash
154 lines
4.8 KiB
Bash
#!/bin/bash
|
|
# Bulk-add orphaned shows to Sonarr from dry-run output
|
|
# Usage: sonarr_bulk_add.sh [--add] (default: dry-run)
|
|
|
|
SONARR_URL="http://localhost:8989"
|
|
SONARR_API_KEY="130decd3db5b4c25afad64864cd03f9f"
|
|
ORPHAN_FILE="/tmp/sonarr_dryrun3.txt"
|
|
ADD_MODE=false
|
|
[[ "${1:-}" == "--add" ]] && ADD_MODE=true
|
|
|
|
declare -A PATH_ROOT=(
|
|
["/mnt/user/Tv_Shows"]="/tv"
|
|
["/mnt/user/Kids_Tv_Shows"]="/kids tv"
|
|
["/mnt/user/Anime_Shows-Old"]="/ext-anime-shows"
|
|
)
|
|
declare -A PATH_QUALITY=(
|
|
["/mnt/user/Tv_Shows"]="6"
|
|
["/mnt/user/Kids_Tv_Shows"]="2"
|
|
["/mnt/user/Anime_Shows-Old"]="6"
|
|
)
|
|
declare -A PATH_TYPE=(
|
|
["/mnt/user/Tv_Shows"]="standard"
|
|
["/mnt/user/Kids_Tv_Shows"]="standard"
|
|
["/mnt/user/Anime_Shows-Old"]="anime"
|
|
)
|
|
|
|
sonarr_get() { curl -sf -H "X-Api-Key: $SONARR_API_KEY" "${SONARR_URL}/api/v3/${1}"; }
|
|
sonarr_post() { curl -sf -X POST -H "X-Api-Key: $SONARR_API_KEY" -H "Content-Type: application/json" -d "$2" "${SONARR_URL}/api/v3/${1}"; }
|
|
|
|
# Build unique list: "fs_root|show_name"
|
|
declare -A SEEN
|
|
declare -a SHOWS
|
|
while IFS= read -r line; do
|
|
fs_root=$(echo "$line" | grep -oP '/mnt/user/[^/]+')
|
|
show_name=$(echo "$line" | grep -oP '/mnt/user/[^/]+/\K[^/]+')
|
|
key="${fs_root}|${show_name}"
|
|
[[ -z "$show_name" || -z "$fs_root" ]] && continue
|
|
[[ -n "${SEEN[$key]:-}" ]] && continue
|
|
SEEN["$key"]=1
|
|
case "$show_name" in
|
|
"Baby.Daddy.S01-S06.1080p.WEB-DL.H.264-ROCCaT"|"Popeye (1960-1961)"|"Tom and Jerry Cartoons Complete Collection (1940-2007)"|"Bugs Bunny"|"2 Stupid Dogs - Super Secret Secret Squirrel")
|
|
echo "SKIP (bad match): $show_name"
|
|
continue ;;
|
|
esac
|
|
SHOWS+=("$key")
|
|
done < <(grep "ORPHAN" "$ORPHAN_FILE")
|
|
|
|
# Get existing series TVDB IDs in Sonarr
|
|
EXISTING_IDS=$(sonarr_get "series" | jq -r '.[].tvdbId')
|
|
|
|
ADDED=0
|
|
SKIPPED=0
|
|
NOT_FOUND=0
|
|
ALREADY=0
|
|
|
|
for entry in "${SHOWS[@]}"; do
|
|
fs_root="${entry%%|*}"
|
|
show_name="${entry##*|}"
|
|
|
|
root_path="${PATH_ROOT[$fs_root]:-}"
|
|
quality_id="${PATH_QUALITY[$fs_root]:-6}"
|
|
series_type="${PATH_TYPE[$fs_root]:-standard}"
|
|
|
|
if [[ -z "$root_path" ]]; then
|
|
echo "SKIP (unknown path): $show_name ($fs_root)"
|
|
(( SKIPPED++ ))
|
|
continue
|
|
fi
|
|
|
|
# Search TVDB via Sonarr lookup
|
|
encoded=$(jq -rn --arg s "$show_name" '$s | @uri')
|
|
result=$(sonarr_get "series/lookup?term=${encoded}" 2>/dev/null)
|
|
if [[ -z "$result" || "$result" == "[]" ]]; then
|
|
echo "NOT FOUND: $show_name"
|
|
(( NOT_FOUND++ ))
|
|
continue
|
|
fi
|
|
|
|
# Pick best match: exact title, then first result
|
|
best=$(echo "$result" | jq --arg name "$show_name" '
|
|
. as $all |
|
|
(map(select(.title | ascii_downcase == ($name | ascii_downcase))) | first) //
|
|
$all[0]
|
|
')
|
|
|
|
tvdb_id=$(echo "$best" | jq -r '.tvdbId // empty')
|
|
matched_title=$(echo "$best" | jq -r '.title // empty')
|
|
year=$(echo "$best" | jq -r '.year // 0')
|
|
|
|
if [[ -z "$tvdb_id" ]]; then
|
|
echo "NOT FOUND: $show_name"
|
|
(( NOT_FOUND++ ))
|
|
continue
|
|
fi
|
|
|
|
# Check by TVDB ID — catches title mismatches (colons, special chars, etc.)
|
|
if echo "$EXISTING_IDS" | grep -q "^${tvdb_id}$"; then
|
|
echo "ALREADY: $show_name (\"$matched_title\" tvdb:$tvdb_id)"
|
|
(( ALREADY++ ))
|
|
continue
|
|
fi
|
|
|
|
if [[ "$ADD_MODE" == false ]]; then
|
|
echo "WOULD ADD: $show_name → \"$matched_title\" ($year) [tvdb:$tvdb_id] [root:$root_path] [type:$series_type]"
|
|
(( ADDED++ ))
|
|
continue
|
|
fi
|
|
|
|
# Build payload from lookup result + our settings
|
|
payload=$(echo "$best" | jq \
|
|
--arg root "$root_path" \
|
|
--argjson qid "$quality_id" \
|
|
--arg stype "$series_type" \
|
|
'{
|
|
tvdbId: .tvdbId,
|
|
title: .title,
|
|
titleSlug: .titleSlug,
|
|
images: .images,
|
|
seasons: .seasons,
|
|
year: .year,
|
|
rootFolderPath: $root,
|
|
qualityProfileId: $qid,
|
|
seriesType: $stype,
|
|
seasonFolder: true,
|
|
monitored: true,
|
|
addOptions: {
|
|
monitor: "all",
|
|
searchForMissingEpisodes: false,
|
|
searchForCutoffUnmetEpisodes: false
|
|
}
|
|
}')
|
|
|
|
response=$(sonarr_post "series" "$payload" 2>&1)
|
|
if echo "$response" | jq -e '.id' &>/dev/null; then
|
|
echo "ADDED: \"$matched_title\" ($year) [tvdb:$tvdb_id]"
|
|
(( ADDED++ ))
|
|
else
|
|
err=$(echo "$response" | jq -r '.[0].errorMessage // .message // "unknown error"' 2>/dev/null)
|
|
echo "FAILED: $show_name → $err"
|
|
(( SKIPPED++ ))
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "━━━ Summary ━━━"
|
|
if [[ "$ADD_MODE" == false ]]; then
|
|
echo "Would add: $ADDED"
|
|
else
|
|
echo "Added: $ADDED"
|
|
fi
|
|
echo "Already in: $ALREADY"
|
|
echo "Not found: $NOT_FOUND"
|
|
echo "Skipped: $SKIPPED"
|