Rework Curator into a Jellyfin-first library manager

This commit is contained in:
2026-08-31 18:34:03 +02:00
parent 1c78ca9013
commit 6a2baf243f
25 changed files with 2420 additions and 1502 deletions
+61
View File
@@ -21,6 +21,67 @@ Each version entry uses these sections (include only those that apply):
## Unreleased
### Added
- **Series support** (Jellyfin TV layout, phase 5; `src/core/series.py`, menu
**Seriály**). Episodes are matched by `SxxEyy` (also `1x02`) and laid out as
`Seriály/Series (rok) [tmdbid]/Season NN/Series SxxEyy.ext` (season 0 →
`Specials`). *"Importovat epizody…"* places episode files (series identified
via TMDb TV lookup, per-file SxxEyy parsed from the filename); *"Přehled
seriálů…"* shows a Series → Season → Episode tree with a naming status and a
per-series **"Přejmenovat epizody"** that renames mis-named episodes into the
right Season folder. `FileManager` gained `load_series`, `import_episodes`,
`rename_episodes_to_canonical`; `tmdb.lookup_tv` / `search_tv` resolve series.
- **NFO-driven genres, ČSFD removed** (phase 4). Curator's metadata source is now
the `.nfo` Jellyfin writes into the media folders (`src/core/nfo.py`, read-only).
*Filmy → "Načíst žánry z NFO"* (`FileManager.refresh_tags_from_nfo`) reads
genre/year/country/rating from each movie's NFO and (re)generates its tags
(user-added tags kept); generating the miniDLNA tree refreshes from NFO first,
so the genre-split tree reflects what Jellyfin knows. The **Filmotéka** menu is
now **miniDLNA** ("Vygenerovat miniDLNA strom").
- **Jellyfin integration** (thin/hybrid, phase 3; `src/core/jellyfin.py`, menu
**Jellyfin**). NFO/artwork on disk stay authoritative; the client only
triggers a scan and reads back what Jellyfin sees. **"Skenovat knihovnu"**
(`POST /Library/Refresh`), **"Ověřit proti poolu…"** (matches pooled movies to
Jellyfin items by TMDb id, then title+year, and reports what is out of sync —
`FileManager.verify_against_jellyfin`), **"Zkontrolovat připojení"**. The
status bar shows the Jellyfin state (nenastaveno / nezkontrolováno / ● verze).
Config via `.env` — `JELLYFIN_URL`, `JELLYFIN_API_KEY`.
- **Movie libraries as physical partitions** (Jellyfin-first, phase 2). The pool
can now hold several top-level movie libraries (`movie_libraries` in the pool
index — default `Filmy`; add Kids/Dokumenty/Anime via *Pool → "Knihovny
(rozdělení)…"*). Import lands in a chosen library, and *Filmy → "Přesunout do
knihovny…"* (context menu too) moves a movie between them. The movie table
gained a **Knihovna** column and a **library filter** (Vše / per library) in
the toolbar. `FileManager` gained `movie_libraries` / `set_movie_libraries`,
`import_movie(library=…)`, `move_to_library`, and `library_of`; `load_pool_movies`
and the consistency check now scan every movie library and skip the sidecars
Jellyfin writes (`.nfo`, artwork, subtitles).
- **TMDb identity source** (`src/core/tmdb.py`) — start of the Jellyfin-first
pivot. Resolves a **TMDb id** (or a title/year search) into a canonical
**title + year**; the rich metadata/artwork are left to Jellyfin. Needs a free
`TMDB_API_KEY` in `.env`; degrades gracefully without it.
- **`[tmdbid-N]` in the pool naming convention** (`naming.py`): the pooled file
is now `Title (YYYY) [tmdbid-N].ext` when the id is known — the exact form
Jellyfin matches on. The id is optional (plain `Title (YYYY)` still valid),
parsed back by `parse_tmdb_id`, preserved across `rename_to_canonical`, and
stripped from the miniDLNA hardlink names (they stay clean `Title.ext`).
`FileManager.import_movie` takes a `tmdb_id`.
### Changed
- **Import reworked around TMDb, ČSFD removed from the import flow.** The import
dialog's "ČSFD odkaz" column is now **TMDb ID**, and **"Dohledat z TMDb"**
fills Title/Year/id (by id, or by searching the filename) — a suggested value
is tinted blue, a name colliding with the pool red. Import no longer fetches
ČSFD tags. (The legacy ČSFD tag actions remain until the tag tree is replaced
by NFO-driven miniDLNA generation.)
### Removed
- **ČSFD entirely.** Deleted `src/core/csfd.py` (scraping, Anubis PoW solver) and
its tests; dropped `File.apply_csfd_tags` / `set_csfd_link` / `get_cached_movie`,
the `csfd_link` field and the ČSFD menu/context actions. `File.csfd_cache` →
`File.meta` and `csfd_tag_paths` → `auto_tag_paths` (both read the old index
keys for back-compat); the folder-name transforms moved to `src/core/transforms.py`.
## 1.11.0 — 2026-07-27
### Added