Add media library reset action
This commit is contained in:
parent
224257e211
commit
81756addf8
3 changed files with 53 additions and 1 deletions
|
|
@ -204,7 +204,7 @@ Discord publishing uses one message with an attached `media-catalog.md` file so
|
|||
|
||||
The dashboard also serves a read-only catalog page at `/catalog`. Set the public reverse-proxy URL for that page in the `Media` tab’s `Catalog URL` field, or with `PUBLIC_CATALOG_URL`, and Discord posts will include an `Open Catalog` button.
|
||||
|
||||
In Jellyfin, create an API key from the admin dashboard, then enter the Jellyfin URL and key in the `Media` tab. If you have duplicate free/premium libraries, enter only the premium Jellyfin library names in the `Libraries` field, separated by commas. `Sync now` replaces the editable library with the current Jellyfin movies and shows while comparing against the previously saved library. `Auto-sync changes` checks Jellyfin periodically and republishes only when the catalog fingerprint changes. Jellyfin results are deduplicated across included libraries using provider IDs first, then normalized title and year.
|
||||
In Jellyfin, create an API key from the admin dashboard, then enter the Jellyfin URL and key in the `Media` tab. If you have duplicate free/premium libraries, enter only the premium Jellyfin library names in the `Libraries` field, separated by commas. `Reset library` clears the saved media list and sync fingerprints. `Sync now` replaces the editable library with the current Jellyfin movies and shows while comparing against the previously saved library. `Auto-sync changes` checks Jellyfin periodically and republishes only when the catalog fingerprint changes. Jellyfin results are deduplicated across included libraries using provider IDs first, then normalized title and year.
|
||||
|
||||
Channel selections are stored in:
|
||||
|
||||
|
|
|
|||
|
|
@ -577,6 +577,7 @@
|
|||
</div>
|
||||
<div class="media-toolbar">
|
||||
<button id="saveJellyfin" type="button">Save Jellyfin</button>
|
||||
<button id="resetMediaLibrary" class="danger" type="button">Reset library</button>
|
||||
<button id="syncJellyfin" type="button">Sync now</button>
|
||||
<button id="forceJellyfinPublish" type="button">Force publish</button>
|
||||
</div>
|
||||
|
|
@ -924,6 +925,18 @@
|
|||
return payload;
|
||||
}
|
||||
|
||||
async function resetMediaLibrary() {
|
||||
setJellyfinMessage("Resetting saved media library...");
|
||||
const payload = await api("/api/media/reset", { method: "POST", body: "{}" });
|
||||
mediaLibrary = normalizeMediaLibrary(payload.library);
|
||||
renderMediaLibrary();
|
||||
renderMediaChanges(payload.changes);
|
||||
document.querySelector("#mediaMovieCount").textContent = payload.movieCount;
|
||||
document.querySelector("#mediaShowCount").textContent = payload.showCount;
|
||||
renderJellyfinStatus(payload);
|
||||
setJellyfinMessage("Saved media library reset. Run Sync now to rebuild it from the selected Jellyfin libraries.");
|
||||
}
|
||||
|
||||
async function syncJellyfin(forcePublish = false) {
|
||||
setJellyfinMessage(forcePublish ? "Syncing and publishing..." : "Syncing Jellyfin...");
|
||||
await saveChannelSettings();
|
||||
|
|
@ -1199,6 +1212,10 @@
|
|||
saveJellyfinSettings().catch((error) => setJellyfinMessage(error.message, true));
|
||||
});
|
||||
|
||||
document.querySelector("#resetMediaLibrary").addEventListener("click", () => {
|
||||
resetMediaLibrary().catch((error) => setJellyfinMessage(error.message, true));
|
||||
});
|
||||
|
||||
document.querySelector("#syncJellyfin").addEventListener("click", () => {
|
||||
syncJellyfin(false).catch((error) => setJellyfinMessage(error.message, true));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -807,6 +807,29 @@ def save_media_library(runtime: BotRuntime, movies: list[MediaItem], shows: list
|
|||
return payload
|
||||
|
||||
|
||||
def reset_media_library(runtime: BotRuntime) -> dict[str, Any]:
|
||||
save_media_library(runtime, [], [])
|
||||
state = load_state(runtime.settings_path)
|
||||
for key in (
|
||||
"jellyfin_last_sync_at",
|
||||
"jellyfin_last_sync_error",
|
||||
"jellyfin_last_published_at",
|
||||
"jellyfin_last_fingerprint",
|
||||
"jellyfin_last_published_fingerprint",
|
||||
"jellyfin_last_changes",
|
||||
):
|
||||
state.pop(key, None)
|
||||
state["updated_at"] = datetime.now(timezone.utc).isoformat()
|
||||
save_state(runtime.settings_path, state)
|
||||
return {
|
||||
"library": media_library_to_jsonable([], []),
|
||||
"movieCount": 0,
|
||||
"showCount": 0,
|
||||
"changes": {"added": [], "removed": [], "addedCount": 0, "removedCount": 0},
|
||||
"jellyfin": jellyfin_settings(runtime),
|
||||
}
|
||||
|
||||
|
||||
def jellyfin_runtime(runtime_ticks: Any) -> str | None:
|
||||
try:
|
||||
ticks = int(runtime_ticks or 0)
|
||||
|
|
@ -1824,6 +1847,9 @@ def make_dashboard_handler(runtime: BotRuntime, auth: DashboardAuth | None) -> t
|
|||
if path == "/api/media/library":
|
||||
self.handle_media_library()
|
||||
return
|
||||
if path == "/api/media/reset":
|
||||
self.handle_media_reset()
|
||||
return
|
||||
if path == "/api/settings":
|
||||
self.handle_settings()
|
||||
return
|
||||
|
|
@ -2061,6 +2087,15 @@ def make_dashboard_handler(runtime: BotRuntime, auth: DashboardAuth | None) -> t
|
|||
},
|
||||
)
|
||||
|
||||
def handle_media_reset(self) -> None:
|
||||
try:
|
||||
result = reset_media_library(runtime)
|
||||
except Exception as exc:
|
||||
self.send_json(HTTPStatus.BAD_REQUEST, {"error": str(exc)})
|
||||
return
|
||||
|
||||
self.send_json(HTTPStatus.OK, result)
|
||||
|
||||
def handle_settings(self) -> None:
|
||||
try:
|
||||
data = self.read_json()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue