Migrate from Poetry and pyenv to uv
This commit is contained in:
+88
-10
@@ -202,19 +202,94 @@ library manager**. Agreed shape:
|
||||
prefixed with the exact folder name — `Title (rok) [tmdbid]/Title (rok)
|
||||
[tmdbid] - {popisek}.ext`; a 3D version's popisek doubles as its 3D tag
|
||||
(`3D HSBS`, scanned by Jellyfin the same as the flat `.3D.HSBS` form).
|
||||
Curator does the promotion/demotion itself (*Upravit film → Verze*); the
|
||||
table always shows one row per movie (`visible_movies`). Shared metadata
|
||||
lives on one **primary** version (`File.is_primary_version`), migrated if
|
||||
that one is ever removed. **Not yet supported:** renaming/moving/retitling
|
||||
a grouped movie (remove the version or edit files directly), and grouped
|
||||
movies inside `mixed` libraries (scoped to `movie`-kind for now — a mixed
|
||||
library's subfolders are still read as series only).
|
||||
Curator does the promotion/demotion itself (*Upravit film → Verze*), and a
|
||||
version's popisek is renamable too (`rename_movie_version`) — a flat movie
|
||||
always shows one placeholder row ("Výchozí") in the list even though it
|
||||
has no on-disk label yet, but renaming only applies once it's grouped. A
|
||||
popisek left empty (a plain "2D" file with nothing else to call it) is
|
||||
`DEFAULT_VERSION_LABEL` ("Výchozí"), not an error — everywhere a popisek is
|
||||
entered (`add_movie_version`, `rename_movie_version`, `merge_as_version`,
|
||||
the import dialog's version link). Promoting/demoting always carries the
|
||||
file's *own* current 3D formát over automatically when no popisek is
|
||||
given for it (`existing_label`/`keep_label` default to `None` → derived
|
||||
via `naming.parse_3d_format`) — a movie can freely gain and lose versions
|
||||
in any order (3D-only → +2D → -3D → 3D-only again, …) without a formát
|
||||
ever getting silently dropped along the way.
|
||||
The default (plain) version of a grouped movie carries **no label**:
|
||||
`Folder/Folder.ext` (`file_manager._version_filename`); "Výchozí" is the
|
||||
UI's name for it. Identity — what decides "is this film already in the
|
||||
pool" — is the folder name for a grouped movie and the stem minus any
|
||||
`.3D.<FORMAT>` for a flat one (`FileManager._identity_stem`,
|
||||
`pooled_with_stem`). Importing a film that's already there defaults to
|
||||
adding a version, never a root-level duplicate, and "keep both as separate
|
||||
films" is not offered for same-TMDb-id films (they'd share one index record).
|
||||
**Parts** (one film split across files, Jellyfin "stacking") are versions
|
||||
with a `partN` popisek, written as `Folder-partN.ext` instead of
|
||||
`Folder - popisek.ext` (`file_manager._version_filename`,
|
||||
`movie.normalize_part_label`); a film with parts always lives in its own
|
||||
folder. Parts and versions in one folder are not combined yet.
|
||||
*Upravit film* presents this as one "Média filmu" section: flat
|
||||
("Samostatný film") until a second medium arrives, then a folder whose
|
||||
mode is switched between versions and parts (`movie_group_mode`,
|
||||
`set_movie_group_mode`); parts are reordered with ↑/↓ (`move_movie_part`).
|
||||
Renames after a relabel go through `File.save_location`, never a plain
|
||||
`save_metadata`, so a stale sibling can't overwrite shared metadata.
|
||||
Custom per-movie attributes are no longer editable in the GUI; stored ones
|
||||
still feed the miniDLNA filename templates.
|
||||
The table always shows one row per movie (`visible_movies`), marked `▣` /
|
||||
`Film · N verze` when it has several; shared metadata lives on the movie
|
||||
record (index v2), so every version reads the same. Accidental duplicates
|
||||
(same tmdbid / title+year / file size as separate movies) are found by
|
||||
*Nástroje → Kontrola duplicit* and folded in via `merge_as_version`.
|
||||
**Not yet supported:** renaming/moving/retitling a grouped movie (remove
|
||||
the version or edit files directly).
|
||||
Works in `mixed` libraries too, disambiguated from a series by **shape**:
|
||||
a movie's version folder and a series folder are both
|
||||
`Title (rok) [tmdbid]/`, but a series always nests episodes in a
|
||||
`Season NN`/`Specials` folder and a movie's version folder never does
|
||||
(`series.looks_like_series_folder`) — `load_pool_movies`/
|
||||
`is_movie_group_member` read the shape and `scan_series`
|
||||
(`skip_movie_folders=True` for `mixed`) skips what it recognises as a
|
||||
movie, so both kinds can share one identity-named folder pair without
|
||||
either leaking into the other's listing. A `series`-kind library (which
|
||||
never holds movies) keeps reading every subfolder as a series regardless
|
||||
of shape, so a raw not-yet-renamed import can still have loose episode
|
||||
files at the series root before `Season NN` exists.
|
||||
Assignable at **import** time too, not just after the fact: picking
|
||||
several files for the same film in one batch (*Importovat filmy…*), a
|
||||
row's "🔗 Přiřadit jako verzi…" marks it a version of another row instead
|
||||
of importing it as its own movie — the earlier attempt at this (a 3D
|
||||
formát combo per row) was rejected because a lone row has nothing to
|
||||
attach the version *to* and just created a duplicate; picking the target
|
||||
row explicitly is what that was missing. The popisek is pre-filled from
|
||||
the filename (`naming.three_d_format_from_filename`) the same way
|
||||
`year_from_filename` pre-fills the year. Import runs the target rows
|
||||
first, then folds each linked row onto its target via
|
||||
`add_movie_version`. The reverse case — a film whose only file *is* 3D,
|
||||
with nothing to link it to — gets its own **3D formát combo per row**
|
||||
instead (`import_movie(..., format_3d=…)`, same as *Upravit film*);
|
||||
disabled the moment the row is linked as a version or gains one as a
|
||||
follower, since a grouped movie's 3D-ness lives on the version's popisek,
|
||||
not on the row that started the group.
|
||||
- Series: `{název série} (rok) [tmdbid]/Season NN/S{ss}E{ee} - {série}.ext`
|
||||
(season 0 → `Specials`). The episode filename is the code + the series title
|
||||
only — the release string is dropped (identity is the code; Jellyfin fetches
|
||||
episode metadata from TMDb via the code + `[tmdbid]`). Episode numbers are
|
||||
recognised from the filename and editable at import / in the series GUI;
|
||||
*Seriály → "Napravit názvy souborů…"* bulk-fixes the whole pool.
|
||||
- **Episodes split into physical parts** (an old recording cut into
|
||||
several files) get Jellyfin's own `.ptN` stacking suffix —
|
||||
`SxxEyy - {série}.ptN.ext` — recognised from *cd/dvd/part/pt/disc/disk* +
|
||||
a number in the source filename (`Show.S01E02.pt2.mkv`,
|
||||
`Show S01E01-part-1.mkv`, …) or typed by hand at import as `S01E02P3`
|
||||
(`src.core.series.parse_episode_code`/`parse_episode_part`). Distinct from
|
||||
a multi-episode file (`E01-E02`, one file = several episodes) — a part is
|
||||
the opposite: several files = one episode.
|
||||
- **Removing a series is scoped to the tree selection**: *Přehled seriálů →
|
||||
"Odebrat z poolu…"* deletes the series, a single season, or a single
|
||||
episode, whichever is selected (`FileManager.remove_series`/
|
||||
`remove_season`/`remove_episodes`) — series still carry no index metadata,
|
||||
so this is always just deleting files/folders from disk.
|
||||
- **CZ title source:** TMDb (cs-CZ) **primarily** — reliable when matched by
|
||||
`tmdbid` (yearless title search picks the wrong film, hence the earlier
|
||||
"weird names"); **ČSFD as fallback/override** (a ČSFD link at import, or when
|
||||
@@ -316,9 +391,12 @@ Note: libraries hold **flat** files for now (`pool/<Library>/Title (rok)
|
||||
|
||||
- Scanning **[done]**: a `mixed` library's top-level files load as movies
|
||||
(`load_pool_movies`), its subfolders as series (`load_series` /
|
||||
`series_libraries` = kind `series` **or** `mixed`, reusing `scan_series`).
|
||||
Both are kind-aware over the unified `libraries` list. The library filter /
|
||||
table already surfaces mixed libraries.
|
||||
`series_libraries` = kind `series` **or** `mixed`, reusing `scan_series`) —
|
||||
*except* a canonical-shaped subfolder with no `Season NN`/`Specials` inside
|
||||
it, which is a movie's version folder instead and loads as a movie too (see
|
||||
"Multiple movie versions" above). Both are kind-aware over the unified
|
||||
`libraries` list. The library filter / table already surfaces mixed
|
||||
libraries.
|
||||
- miniDLNA generation **[done]**: a mixed library's movies are genre-tagged as
|
||||
usual; series in its subfolders have no genre tags, so they're hardcopied
|
||||
straight into `output/Seriály/<název>/…` instead
|
||||
|
||||
Reference in New Issue
Block a user