Fix poster scan losing items whose title contains a quote
posters_scan passed each line to the worker with `xargs -I{}`, which splices
the text straight into the shell command. Any title containing an apostrophe
or a quote became a shell syntax error and that item was dropped — silently,
since the error went to stderr while the audit counted only what came back.
No show title happened to trigger it, so this survived the show-level work.
The first episode-level scan hit it immediately: titles like "That's a shirt?"
and "WAIT A MINUTE, ..." produced `unexpected EOF while looking for matching
quote`, which means that episode run reported nothing trustworthy.
Lines are now passed as a positional argument, so the shell never parses their
content. Regression-tested with titles containing apostrophes, double quotes,
commas, backticks and $(...) — all handled, and the $(...) case confirmed not
to execute.
Also tightens the check itself: a poster is OK only if the response is 200
*and* an image content-type. Plex answers some paths with 200 and an XML body,
which the status-only check counted as a working poster.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
29476235ab
commit
eaf91b157b
+13
-5
@@ -57,19 +57,27 @@ posters_scan() {
|
|||||||
# Items with no thumb field at all need no HTTP request.
|
# Items with no thumb field at all need no HTTP request.
|
||||||
jq -r '.MediaContainer.Metadata[]?|select(has("thumb")|not)|"\(.ratingKey)\tMISSING\t\(.title)"' "$items_json"
|
jq -r '.MediaContainer.Metadata[]?|select(has("thumb")|not)|"\(.ratingKey)\tMISSING\t\(.title)"' "$items_json"
|
||||||
|
|
||||||
|
# Each line is passed to the worker as a positional ARGUMENT ($1), never
|
||||||
|
# substituted into the command text. `xargs -I{}` would splice the title
|
||||||
|
# straight into the shell string, so a title containing an apostrophe or a
|
||||||
|
# quote — "That's", 'MINUTE,' — becomes a syntax error and that item is
|
||||||
|
# silently lost. Real titles at episode scale are full of them.
|
||||||
jq -r '.MediaContainer.Metadata[]?|select(has("thumb"))|"\(.ratingKey)\t\(.thumb)\t\(.title)"' "$items_json" \
|
jq -r '.MediaContainer.Metadata[]?|select(has("thumb"))|"\(.ratingKey)\t\(.thumb)\t\(.title)"' "$items_json" \
|
||||||
| PLEX_URL="$PLEX_URL" PLEX_TOKEN="$PLEX_TOKEN" PLEX_INSECURE="${PLEX_INSECURE:-0}" \
|
| PLEX_URL="$PLEX_URL" PLEX_TOKEN="$PLEX_TOKEN" PLEX_INSECURE="${PLEX_INSECURE:-0}" \
|
||||||
xargs -P "$jobs" -d '\n' -I{} bash -c '
|
xargs -P "$jobs" -d '\n' -n 1 bash -c '
|
||||||
IFS=$'"'"'\t'"'"' read -r rk thumb title <<<"{}"
|
IFS=" " read -r rk thumb title <<<"$1"
|
||||||
flags=(--silent --show-error --max-time 30)
|
flags=(--silent --show-error --max-time 30)
|
||||||
[[ "${PLEX_INSECURE:-0}" == "1" ]] && flags+=(--insecure)
|
[[ "${PLEX_INSECURE:-0}" == "1" ]] && flags+=(--insecure)
|
||||||
code=$(curl "${flags[@]}" -o /dev/null -w "%{http_code}" \
|
# Status alone is not proof of a poster: Plex answers some paths with
|
||||||
|
# HTTP 200 and an XML or HTML body. Require an image content-type.
|
||||||
|
read -r code ctype < <(curl "${flags[@]}" -o /dev/null \
|
||||||
|
-w "%{http_code} %{content_type}" \
|
||||||
-H "X-Plex-Token: ${PLEX_TOKEN}" "${PLEX_URL%/}${thumb}")
|
-H "X-Plex-Token: ${PLEX_TOKEN}" "${PLEX_URL%/}${thumb}")
|
||||||
if [[ "$code" == "200" ]]; then
|
if [[ "$code" == "200" && "$ctype" == image/* ]]; then
|
||||||
printf "%s\tOK\t%s\n" "$rk" "$title"
|
printf "%s\tOK\t%s\n" "$rk" "$title"
|
||||||
else
|
else
|
||||||
printf "%s\tBROKEN\t%s\n" "$rk" "$title"
|
printf "%s\tBROKEN\t%s\n" "$rk" "$title"
|
||||||
fi'
|
fi' _
|
||||||
}
|
}
|
||||||
|
|
||||||
# Echo the best poster candidate URL for an item, or nothing if there is none.
|
# Echo the best poster candidate URL for an item, or nothing if there is none.
|
||||||
|
|||||||
Reference in New Issue
Block a user