legacy-arrflix/bin/fix-home-db.sh
s8n 0122de7041
Some checks are pending
secret-scan / gitleaks (HEAD + history) (push) Waiting to run
secret-scan / detect-secrets (entropy + cross-tool) (push) Waiting to run
secret-scan / summary (push) Blocked by required conditions
bin: add fix-home-db.sh — direct SQLite seed for HomeSection table
The Jellyfin 10.10.3 REST endpoint won't INSERT HomeSection rows for the
'Jellyfin Web' client (only updates existing rows), so users whose web-
client DisplayPreferences was created without explicit home-section state
fall back to factory defaults that include Next Up. Applying CustomPrefs
via API doesn't help — the web client reads HomeSection rows.

Direct DB seed: for every DisplayPreferences row with zero HomeSection
rows, insert [Resume, LatestMedia, None*8]. Also replace Type=7 (NextUp)
with Type=0 (None) across all DPs. Idempotent.

Applied 2026-05-11 across prod (13 users) and dev (1 user). Verified
yummyhunny home now shows Continue Watching above Latest Media.
2026-05-11 03:20:24 +01:00

73 lines
3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Direct SQLite fix for Jellyfin 10.10.3 home-screen sections.
#
# Why this exists:
# The REST endpoint `POST /DisplayPreferences/usersettings?client=Jellyfin Web`
# updates `DisplayPreferences.CustomPrefs` but does NOT insert into the
# `HomeSection` table for that client (it only inserts when called with
# client="emby"). The web client reads from `HomeSection` rows on the
# `Jellyfin Web` DisplayPreferences row, so the legacy POST has no
# visible effect until those rows exist.
#
# What this script does (idempotent):
# 1. Insert a `Jellyfin Web` DisplayPreferences row for any user missing one.
# 2. Seed canonical home layout [Resume, LatestMedia, None*8] for every
# DisplayPreferences row that has zero HomeSection rows.
# 3. Replace any Type=7 (NextUp) with Type=0 (None) across the table.
#
# Type integers (Jellyfin.Data.Enums.HomeSectionType):
# 0=None, 1=SmallLibraryTiles, 2=LibraryButtons, 3=ActiveRecordings,
# 4=Resume, 5=ResumeAudio, 6=LatestMedia, 7=NextUp, 8=LiveTv, 9=ResumeBook
#
# Container must be stopped during write to avoid corrupting the EF Core
# WAL. After write, restart the container.
#
# Usage:
# docker stop jellyfin
# DB=/home/docker/jellyfin/config/data/jellyfin.db bin/fix-home-db.sh
# docker start jellyfin
set -euo pipefail
DB="${DB:-/home/docker/jellyfin/config/data/jellyfin.db}"
[ -f "$DB" ] || { echo "DB not found at $DB"; exit 1; }
cp -n "$DB" "$DB.bak.$(date +%s)"
sqlite3 "$DB" <<'SQL'
.bail on
BEGIN;
-- 1) Create Jellyfin Web DP row for users missing one.
INSERT INTO DisplayPreferences (UserId, Client, ShowSidebar, ShowBackdrop, ScrollDirection,
SkipForwardLength, SkipBackwardLength, ChromecastVersion,
EnableNextVideoInfoOverlay, ItemId)
SELECT u.Id, 'Jellyfin Web', 0, 1, 0, 30000, 10000, 0, 0, '00000000-0000-0000-0000-000000000000'
FROM Users u
WHERE NOT EXISTS (
SELECT 1 FROM DisplayPreferences d
WHERE UPPER(d.UserId) = UPPER(u.Id) AND d.Client = 'Jellyfin Web'
);
-- 2) For any DP with zero HomeSection rows, seed [Resume, LatestMedia, None*8].
INSERT INTO HomeSection (DisplayPreferencesId, "Order", Type)
SELECT d.Id, 0, 4 FROM DisplayPreferences d
WHERE NOT EXISTS (SELECT 1 FROM HomeSection h WHERE h.DisplayPreferencesId=d.Id);
INSERT INTO HomeSection (DisplayPreferencesId, "Order", Type)
SELECT d.Id, 1, 6 FROM DisplayPreferences d
WHERE (SELECT COUNT(*) FROM HomeSection h WHERE h.DisplayPreferencesId=d.Id) = 1;
INSERT INTO HomeSection (DisplayPreferencesId, "Order", Type)
SELECT d.Id, ord, 0 FROM DisplayPreferences d
CROSS JOIN (SELECT 2 AS ord UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9)
WHERE (SELECT COUNT(*) FROM HomeSection h WHERE h.DisplayPreferencesId=d.Id) = 2;
-- 3) Replace NextUp (7) with None (0) across all DPs.
UPDATE HomeSection SET Type = 0 WHERE Type = 7;
COMMIT;
SQL
echo "[+] $DB normalized"
echo "=== type summary ==="
sqlite3 "$DB" "SELECT Type, COUNT(*) FROM HomeSection GROUP BY Type"