Add watchlist filesystem reconciliation

This commit is contained in:
Codex
2026-07-21 09:41:24 +02:00
parent ef2df14aab
commit 0e40c9bda9
7 changed files with 332 additions and 4 deletions
+46 -1
View File
@@ -612,6 +612,18 @@ CONFIG_HTML = r"""<!doctype html>
<div class="muted" id="jellyfinSyncStatus">No recent Jellyfin handoff job.</div>
</section>
<section class="settings settings-main">
<div class="toolbar">
<div>
<h2>Watchlist filesystem sync</h2>
<p class="muted">Manually reconcile downloaded episode flags with the files currently present under the download library.</p>
</div>
<button id="reconcileWatchlistDownloadsBtn" type="button">Sync now</button>
</div>
<div class="field-hint">This scans the configured download library, removes downloaded episode flags for files that no longer exist, and adds flags for episodes already present on disk.</div>
<div class="muted" id="watchlistReconcileStatus">No watchlist filesystem sync run yet.</div>
</section>
<section class="settings settings-main">
<div class="toolbar">
<div>
@@ -706,7 +718,8 @@ CONFIG_HTML = r"""<!doctype html>
home_path: ""
},
jellyfinSyncRunning: false,
jellyfinSyncJobId: null
jellyfinSyncJobId: null,
watchlistReconcileRunning: false
};
const $ = (id) => document.getElementById(id);
@@ -743,6 +756,15 @@ CONFIG_HTML = r"""<!doctype html>
el.textContent = job.message || "Jellyfin handoff idle.";
}
function setWatchlistReconcileButton(running) {
$("reconcileWatchlistDownloadsBtn").disabled = !!running;
$("reconcileWatchlistDownloadsBtn").textContent = running ? "Syncing..." : "Sync now";
}
function setWatchlistReconcileStatus(text) {
$("watchlistReconcileStatus").textContent = text || "No watchlist filesystem sync run yet.";
}
function selectedWebhookEvents() {
return [...document.querySelectorAll(".webhook-event:checked")].map((input) => input.value);
}
@@ -862,6 +884,28 @@ CONFIG_HTML = r"""<!doctype html>
}
}
async function reconcileWatchlistDownloads() {
state.watchlistReconcileRunning = true;
setWatchlistReconcileButton(true);
setWatchlistReconcileStatus("Scanning the download library...");
try {
const data = await api("/api/config/watchlist/reconcile-downloads", {
method: "POST",
body: JSON.stringify(formConfigPayload())
});
const changed = Number(data.changed || 0);
const total = Number(data.total || 0);
setWatchlistReconcileStatus(`${changed} updated out of ${total} watchlist entries.`);
setNotice(data.message || "Watchlist filesystem sync completed.");
} catch (error) {
setWatchlistReconcileStatus("Watchlist filesystem sync failed.");
setNotice(error.message);
} finally {
state.watchlistReconcileRunning = false;
setWatchlistReconcileButton(false);
}
}
function closePathBrowser() {
state.pathBrowser = {
targetId: "",
@@ -1008,6 +1052,7 @@ CONFIG_HTML = r"""<!doctype html>
$("saveConfigBtn").addEventListener("click", saveConfig);
$("testWebhookBtn").addEventListener("click", testWebhook);
$("runJellyfinSyncBtn").addEventListener("click", runJellyfinSync);
$("reconcileWatchlistDownloadsBtn").addEventListener("click", reconcileWatchlistDownloads);
$("openChangelogBtn").addEventListener("click", openChangelog);
$("closeChangelogBtn").addEventListener("click", closeChangelog);
$("pathBrowserCloseBtn").addEventListener("click", closePathBrowser);