Add Jellyfin library handoff controls

This commit is contained in:
Dymas
2026-05-25 17:10:23 +02:00
parent 139d7d9e2f
commit ece4ce0d5e
8 changed files with 371 additions and 28 deletions
+47
View File
@@ -431,6 +431,31 @@ CONFIG_HTML = r"""<!doctype html>
<div class="field-hint">Adding a new watchlist entry does not auto-download anything. Auto-download only reacts to later manual refreshes or scheduled refreshes that find new episodes.</div>
</section>
<section class="settings settings-main">
<div class="toolbar">
<div>
<h2>Jellyfin handoff</h2>
<p class="muted">Move fully completed anime libraries from the default download area into the folders that Jellyfin scans.</p>
</div>
<button id="runJellyfinSyncBtn" type="button">Run now</button>
</div>
<div class="form-grid">
<label>Automatic handoff
<select id="jellyfinSyncEnabled">
<option value="false">Disabled</option>
<option value="true">Enabled</option>
</select>
</label>
<label>Jellyfin TV library
<input id="jellyfinTvDir" placeholder="/srv/media/anime-tv">
</label>
<label>Jellyfin movie library
<input id="jellyfinMovieDir" placeholder="/srv/media/anime-movies">
</label>
</div>
<div class="field-hint">TV entries move only after the show is marked `Finished` and at least one downloaded language covers the expected episode count. Movie entries move after they are downloaded. The manual trigger scans the current watchlist and moves anything already eligible.</div>
</section>
<section class="settings settings-main">
<div class="toolbar">
<div>
@@ -468,6 +493,9 @@ CONFIG_HTML = r"""<!doctype html>
auto_download_enabled: false,
auto_download_mode: "dub",
auto_download_quality: "best",
jellyfin_sync_enabled: false,
jellyfin_tv_dir: "",
jellyfin_movie_dir: "",
discord_webhook_url: "",
discord_webhook_events: []
}
@@ -495,6 +523,9 @@ CONFIG_HTML = r"""<!doctype html>
auto_download_enabled: $("autoDownloadEnabled").value === "true",
auto_download_mode: $("autoDownloadMode").value,
auto_download_quality: $("autoDownloadQuality").value,
jellyfin_sync_enabled: $("jellyfinSyncEnabled").value === "true",
jellyfin_tv_dir: $("jellyfinTvDir").value,
jellyfin_movie_dir: $("jellyfinMovieDir").value,
discord_webhook_url: $("discordWebhookUrl").value,
discord_webhook_events: selectedWebhookEvents()
};
@@ -511,6 +542,9 @@ CONFIG_HTML = r"""<!doctype html>
$("autoDownloadEnabled").value = String(Boolean(data.auto_download_enabled));
$("autoDownloadMode").value = data.auto_download_mode;
$("autoDownloadQuality").value = data.auto_download_quality;
$("jellyfinSyncEnabled").value = String(Boolean(data.jellyfin_sync_enabled));
$("jellyfinTvDir").value = data.jellyfin_tv_dir || "";
$("jellyfinMovieDir").value = data.jellyfin_movie_dir || "";
$("discordWebhookUrl").value = data.discord_webhook_url || "";
const selected = new Set(data.discord_webhook_events || []);
for (const input of document.querySelectorAll(".webhook-event")) {
@@ -546,6 +580,18 @@ CONFIG_HTML = r"""<!doctype html>
}
}
async function runJellyfinSync() {
try {
const data = await api("/api/config/jellyfin/sync", {
method: "POST",
body: JSON.stringify(formConfigPayload())
});
setNotice(data.message || "Jellyfin handoff completed.");
} catch (error) {
setNotice(error.message);
}
}
async function loadDeps() {
const data = await api("/api/dependencies");
const el = $("deps");
@@ -569,6 +615,7 @@ CONFIG_HTML = r"""<!doctype html>
$("saveConfigBtn").addEventListener("click", saveConfig);
$("testWebhookBtn").addEventListener("click", testWebhook);
$("runJellyfinSyncBtn").addEventListener("click", runJellyfinSync);
(async function init() {
try {