ARRFLIX/bin/apply-26-incident-fixes.sh
s8n 549c86efdf doc 26 + bin: incident 2026-05-09 + headless smoke-test
Symptoms: Page Unresponsive on poster grid, posters missing then black
backdrops, 'Abspielen' German Play button surviving Traefik+force-english
chases, video black-screen on play.

Root causes (different from initial guesses):
- Browser hangs: deployed index.html drifted ahead of repo; uncommitted
  forceEnglishUI() text-walker MutationObserver froze main thread on poster
  lazy-load. Reverted to repo HEAD.
- 'Abspielen': Cineplex theme HARDCODES German via 'content:' ::after rule
  -- not a Jellyfin locale issue. Doc 25 already proved per-user UICulture
  is theatre. Override CSS with content: 'Play'.
- Backdrops black: BLACK-PASS CustomCss block paints #000 !important on
  .layout-desktop / .pageContainer -- occludes backdrop layer (z-index:-1).
  Existing transparent-scope rule used body.itemDetailPage selector that
  doesn't match in 10.10.3 (body class is libraryDocument). Replaced with
  :has(.itemDetailPage) ancestor scoping.
- HLS 499: encoding.xml had EnableThrottling+EnableSegmentDeletion=true,
  segments reaped before browser re-request. Disabled both.

Verified via new bin/headless-test.py (playwright Chromium login + screenshot
+ computed-style probe). Fixes idempotent and re-runnable via new
bin/apply-26-incident-fixes.sh.

Open: AV1+Opus items still black-screen in Chrome due to DirectStream
codec-tag mislabel bug. Tracked for 10.11.8 migration.
2026-05-09 01:11:38 +01:00

80 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
# apply-26-incident-fixes.sh
#
# Re-applies the three server-state fixes from docs/26 if branding.xml /
# encoding.xml drift back to broken state (e.g. after a Jellyfin restore).
#
# 1. CustomCss: Cineplex hardcoded "Abspielen" → "Play"
# 2. CustomCss: Backdrop transparent-scope using :has() (BLACK-PASS occluded backdrop layer)
# 3. encoding.xml: EnableThrottling=false + EnableSegmentDeletion=false (kills HLS 499)
#
# Usage: ssh user@nullstone "$(cat bin/apply-26-incident-fixes.sh)"
# Idempotent: re-running is safe.
set -euo pipefail
# 3. encoding.xml — disable throttling + segment deletion (both containers if present)
for cfg in /home/docker/jellyfin/config/config/encoding.xml \
/home/docker/jellyfin-dev/config/config/encoding.xml; do
[ -f "$cfg" ] || continue
cp -n "$cfg" "$cfg.bak.pre-doc26" || true
sed -i \
-e 's|<EnableThrottling>true</EnableThrottling>|<EnableThrottling>false</EnableThrottling>|' \
-e 's|<EnableSegmentDeletion>true</EnableSegmentDeletion>|<EnableSegmentDeletion>false</EnableSegmentDeletion>|' \
"$cfg"
echo "[+] patched $cfg"
done
# 1+2. branding.xml CustomCss — Abspielen + backdrop transparent-scope
patch_branding() {
local cfg="$1"
[ -f "$cfg" ] || return 0
if grep -q "ARRFLIX 2026-05-09" "$cfg"; then
echo "[=] $cfg already has doc-26 patch"
return 0
fi
cp -n "$cfg" "$cfg.bak.pre-doc26" || true
python3 - <<PY
p = "$cfg"
s = open(p).read()
patch = """
/* ARRFLIX 2026-05-09 — incident fixes (see docs/26-incident-2026-05-09-...).
1. Cineplex theme hardcodes German "Abspielen" via ::after on .play_arrow.
Override with English. The German text was in CSS, not Jellyfin locale —
so all Traefik Accept-Language rewrites + force-english-all-users.sh
chases never fixed it.
2. The BLACK-PASS block paints #000 !important on .layout-desktop,
.pageContainer, .padded-bottom-page etc — these wrap the backdrop layer
(z-index:-1) and occlude it. Use :has() to scope only when an
.itemDetailPage descendant exists, so backdrop renders only on detail
pages. */
.mainDetailButtons .material-icons.play_arrow::after {
content: "Play" !important;
}
.itemDetailPage,
.layout-desktop:has(.itemDetailPage),
.layout-mobile:has(.itemDetailPage),
.layout-tv:has(.itemDetailPage),
.mainAnimatedPages:has(.itemDetailPage),
.pageContainer:has(.itemDetailPage),
.padded-bottom-page:has(.itemDetailPage),
.libraryPage:has(.itemDetailPage),
.absolutePageTabContent:has(.itemDetailPage) {
background-color: transparent !important;
background: transparent !important;
}
"""
s = s.replace("</CustomCss>", patch + "</CustomCss>")
open(p, "w").write(s)
PY
echo "[+] patched $cfg"
}
patch_branding /home/docker/jellyfin/config/config/branding.xml
patch_branding /home/docker/jellyfin-dev/config/config/branding.xml
# Restart so changes take effect
docker restart jellyfin jellyfin-dev 2>/dev/null || docker restart jellyfin
echo "[*] Done. Verify with bin/headless-test.py."