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.
|
||||
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" \
|
||||
| PLEX_URL="$PLEX_URL" PLEX_TOKEN="$PLEX_TOKEN" PLEX_INSECURE="${PLEX_INSECURE:-0}" \
|
||||
xargs -P "$jobs" -d '\n' -I{} bash -c '
|
||||
IFS=$'"'"'\t'"'"' read -r rk thumb title <<<"{}"
|
||||
xargs -P "$jobs" -d '\n' -n 1 bash -c '
|
||||
IFS=" " read -r rk thumb title <<<"$1"
|
||||
flags=(--silent --show-error --max-time 30)
|
||||
[[ "${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}")
|
||||
if [[ "$code" == "200" ]]; then
|
||||
if [[ "$code" == "200" && "$ctype" == image/* ]]; then
|
||||
printf "%s\tOK\t%s\n" "$rk" "$title"
|
||||
else
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user