@deckyard/jellyfin
Jellyfin is a self-hosted media server for films, shows, music and photos. This deck is a client for its REST API: sign in, browse and search what a user sees, keep track of what was played, fetch posters, and look after the server (users, library scans, scheduled tasks, the clients playing right now).
- Signing in: passwords, API keys, users, devices.
- The library: libraries, items, paging, search, resume, next up, played and favourite marks, images.
- Administration: the server, users, scans, tasks, sessions.
- Cheatsheet: every export.
Conventions
Snippets assume this import:
import "@deckyard/jellyfin/" as jellyfin;A request the server refused throws jellyfin.HttpError, kind jellyfin.http, with the HTTP status and the validation errors as fields; any other failure is Error{kind: "jellyfin"} (a cancelled task stays "task cancelled"):
try {
def it as jellyfin.Item init jellyfin.item($c, $id);
} catch (e) {
if ($e.kind == "jellyfin.http" and $e.status == 404) {
io.printf("no such item\n");
} else {
throw $e;
}
}Every request has a deadline (30 s) and a response cap (16 MiB). Plain http is refused except to this machine, because the password and token would cross the network in clear; a server on the LAN without TLS needs withPlainHttp. Ids, query parameter names and paths are checked before they go into a URL.
The deck follows the Jellyfin 10.9-and-later API (user ids as query parameters, /UserViews, /UserItems/Resume, /UserPlayedItems). It needs the net capability and does not run on jennifer-tiny.