# Personal Recordings (Jellyfin plugin) Tracks which Jellyfin user scheduled a Live TV recording and moves completed files into `{TargetRoot}/{Username}/` (default `/recordings/Bram`). Jellyfin core does not store timer ownership. This plugin captures the authenticated user on `TimerCreated` / `SeriesTimerCreated` (via `HttpContext`) and later moves completed recordings. ## Requirements - Jellyfin **10.11.x** (ABI `10.11.0.0`, `net9.0`) - Live TV recordings enabled - Writable target root (e.g. mount `/recordings` into the Jellyfin container) ## Install ### Catalog (Gitea) 1. Build/release via tag (see below), or wait for CI 2. In Jellyfin: **Dashboard → Plugins → Repositories → +** 3. Repository URL (raw catalog): ```text https://///raw/branch//Jellyfin/manifest.json ``` 4. Catalog → install **Personal Recordings** → restart Jellyfin ### Manual ```bash dotnet build -c Release # copy Jellyfin.Plugin.PersonalRecordings/bin/Release/net9.0/Jellyfin.Plugin.PersonalRecordings.dll # into /plugins/PersonalRecordings/ ``` Restart Jellyfin. ## Configuration | Setting | Default | Meaning | |---|---|---| | Enabled | true | Master switch | | Target root path | `/recordings` | Files go to `{path}/{Username}/` | | Poll interval | 60 | Seconds between completion checks | | Dry run | false | Log only, no file moves | ## Release (monorepo CI) ```bash git tag jellyfin/jellyfin-plugin-personal-recordings/v1.0.0 git push origin jellyfin/jellyfin-plugin-personal-recordings/v1.0.0 ``` Workflow: [`.gitea/workflows/release_jellyfin_plugin.yml`](../../.gitea/workflows/release_jellyfin_plugin.yml) ## New plugins under `Jellyfin/` Use **Actions → Scaffold Jellyfin plugin** (`scaffold_jellyfin_plugin.yml`) with a slug like `jellyfin-plugin-myfeature`. That creates boilerplate from `Jellyfin/_template/` and registers the plugin in `Jellyfin/manifest.json`. ## Notes - Series child timers inherit ownership from the series timer when there is no HTTP user. - Moves run only when timer status is **Completed**. - Sidecar files (`*.nfo`, images with the same basename) are moved best-effort.