3.2 KiB
Curator
Curator is a PySide6 desktop app for managing a Jellyfin-first movie and series library. You import video files into a managed pool; Curator identifies them through TMDb, names and lays them out the way Jellyfin expects, and can generate a genre-split miniDLNA / Filmotéka tree of hardlinks for dumb DLNA players — without ever duplicating the video data on disk.
Metadata (posters, plots, .nfo files) is Jellyfin's job; Curator owns the files,
their names and the library structure.
Concepts
-
Pool — the managed folder and the single source of truth. Curator imports, renames and removes files itself, so nothing moves behind its back. Each top-level folder is a library with a kind:
Kind Holds Layout moviemovies Title (rok) [tmdbid].ext, or a folder once a film has several versionsseriesseries Series (rok) [tmdbid]/Season NN/SxxEyy - Series.extmixedmovies and series together as above, side by side homevideofiles without a TMDb id mirrored as-is -
Pool index — Curator's own metadata (TMDb id, ČSFD link, versions, tags, library settings) lives in one
.Curator.!indexJSON file at the pool root. -
miniDLNA output — a generated tree of hardlinks into the pool, built from the genres/years/ratings in Jellyfin's NFO files. It is disposable: delete it and regenerate it at any time.
Features
- Import movies and episodes with a mandatory TMDb id; Czech titles come from TMDb, with ČSFD as a fallback and as a bridge for finding the right TMDb id.
- Multiple versions of one film (2D/3D, 4K, director's cut) and multi-part films and episodes, named so Jellyfin groups them.
- Subtitle sidecars follow their video through renames.
- Duplicate check, video integrity check (FFmpeg), library statistics.
- Jellyfin integration: trigger a library scan, read what Jellyfin has.
- miniDLNA tree scoped per library, with "Tipy dne" and "Nově přidané" folders.
Requirements
- uv — manages Python 3.14 and all dependencies
ffmpeg/ffprobeonPATH— optional, for the integrity check
Configuration
Secrets and settings are read from a .env file in the project root (never
committed):
| Variable | Purpose |
|---|---|
TMDB_API_KEY |
TMDb API key — required for identifying movies and series |
TMDB_LANGUAGE |
TMDb language, default cs-CZ |
JELLYFIN_URL |
Jellyfin server URL — optional, for the Jellyfin menu |
JELLYFIN_API_KEY |
Jellyfin API key — optional |
ENV_DEBUG |
true enables debug mode |
The pool and output folders are chosen in the app (Pool menu).
Running
uv sync
uv run python Curator.py
Development
uv run pytest # tests
uv run ruff check # lint
uv run ruff format # format
uv run mypy # type checking
Detailed documentation — architecture and a per-module reference — is in
docs/.
Building a standalone executable
uv run python prebuild.py
uv run pyinstaller Curator.spec --noconfirm
The result is a single self-contained dist/Curator executable.