Fix try_smart_import() silently failing every ManualImport it fires
The candidate objects from /manualimport only nest ids under .series.id and .movie.id, but Sonarr/Radarr's ManualImport command requires them flattened to top-level seriesId/episodeIds or movieId — every call was failing instantly with "Series/Movie with ID 0 does not exist" while the caller only checked for HTTP 201 (accepted), so every "smart-imported" this script has ever logged was actually a silent no-op. Now flattens the ids before submitting and briefly polls the command afterward so a fast failure falls through to the normal blocklist+research path instead of being reported as success.
This commit is contained in:
@@ -378,6 +378,14 @@ try_smart_import() {
|
||||
existing_res=$(echo "$existing" | jq -r '.episodeFile.quality.quality.resolution // 0' 2>/dev/null)
|
||||
existing_lang=$(echo "$existing" | jq -r '.episodeFile.languages[0].name // "Unknown"' 2>/dev/null)
|
||||
fi
|
||||
# /manualimport only nests the IDs under .series.id / .episodes[].id —
|
||||
# the ManualImport command body needs them flattened to top-level
|
||||
# seriesId/episodeIds or Sonarr rejects the whole command with
|
||||
# "Series with ID 0 does not exist" (confirmed live 2026-07-19: every
|
||||
# smart-import this run reported as successful had actually failed
|
||||
# this way, silently, since the caller only checks the HTTP 201 accept).
|
||||
entry=$(echo "$entry" | jq -c --argjson eid "$target_id" \
|
||||
'. + {seriesId: .series.id, episodeIds: [$eid]}' 2>/dev/null)
|
||||
;;
|
||||
radarr)
|
||||
target_id=$(echo "$entry" | jq -r '.movie.id // empty' 2>/dev/null)
|
||||
@@ -391,10 +399,14 @@ try_smart_import() {
|
||||
existing_res=$(echo "$existing" | jq -r '.quality.quality.resolution // 0' 2>/dev/null)
|
||||
existing_lang=$(echo "$existing" | jq -r '.languages[0].name // "Unknown"' 2>/dev/null)
|
||||
fi
|
||||
# Same flattening issue as Sonarr above — command body needs a
|
||||
# top-level movieId or Radarr rejects it with "Movie with ID 0
|
||||
# does not exist".
|
||||
entry=$(echo "$entry" | jq -c --argjson mid "$target_id" '. + {movieId: $mid}' 2>/dev/null)
|
||||
;;
|
||||
esac
|
||||
|
||||
[[ -z "$target_id" ]] && return 1
|
||||
[[ -z "$target_id" || -z "$entry" ]] && return 1
|
||||
|
||||
if [[ "$has_file" != "true" ]]; then
|
||||
decision="import" # nothing there yet — fills a real gap
|
||||
@@ -419,19 +431,36 @@ try_smart_import() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
local files_json cmd_body http_code
|
||||
local files_json cmd_body response http_code cmd_id cmd_status
|
||||
files_json=$(printf '%s\n' "${qualifying_files[@]}" | jq -s -c '.' 2>/dev/null)
|
||||
[[ -z "$files_json" ]] && return 1
|
||||
cmd_body=$(jq -c -n --argjson files "$files_json" \
|
||||
'{name:"ManualImport", files:$files, importMode:"auto"}' 2>/dev/null)
|
||||
[[ -z "$cmd_body" ]] && return 1
|
||||
|
||||
http_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
|
||||
response=$(curl -s -w '\n%{http_code}' -X POST \
|
||||
-H "X-Api-Key: $api_key" -H "Content-Type: application/json" \
|
||||
-d "$cmd_body" \
|
||||
"${url}/api/${api_version}/command" 2>/dev/null)
|
||||
http_code=$(echo "$response" | tail -1)
|
||||
cmd_id=$(echo "$response" | head -n -1 | jq -r '.id // empty' 2>/dev/null)
|
||||
|
||||
[[ "$http_code" == "201" ]]
|
||||
[[ "$http_code" != "201" || -z "$cmd_id" ]] && return 1
|
||||
|
||||
# A bad payload (e.g. the seriesId/movieId=0 bug this was written to catch)
|
||||
# fails in ~10ms — well before any real file copy would even start — so a
|
||||
# brief poll here catches that failure class without racing a genuinely
|
||||
# long-running import, which is the reason this doesn't poll to completion.
|
||||
local _i
|
||||
for _i in 1 2 3; do
|
||||
sleep 1
|
||||
cmd_status=$(curl -sf --max-time 10 -H "X-Api-Key: $api_key" \
|
||||
"${url}/api/${api_version}/command/${cmd_id}" 2>/dev/null | jq -r '.status // empty')
|
||||
[[ "$cmd_status" == "failed" ]] && return 1
|
||||
[[ "$cmd_status" == "completed" ]] && break
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ==============================================================================================
|
||||
|
||||
Reference in New Issue
Block a user