Migrate from Poetry and pyenv to uv

This commit is contained in:
2026-10-12 15:48:26 +02:00
parent c399a6aed3
commit c69f5f9166
93 changed files with 13068 additions and 2401 deletions
+104 -35
View File
@@ -1,4 +1,5 @@
"""Tests for the movie object and the pool layout it derives (src.core.movie)."""
from pathlib import Path
import pytest
@@ -13,34 +14,54 @@ from src.core.movie import (
)
@pytest.mark.parametrize("label,expected", [
("HSBS", "HSBS"), ("hsbs", "HSBS"), ("3D HSBS", "HSBS"),
("3d.hsbs", "HSBS"), ("3D_FTAB", "FTAB"), ("3d-mvc", "MVC"),
("4K", None), ("Director's Cut", None), ("", None), (None, None),
])
@pytest.mark.parametrize(
"label,expected",
[
("HSBS", "HSBS"),
("hsbs", "HSBS"),
("3D HSBS", "HSBS"),
("3d.hsbs", "HSBS"),
("3D_FTAB", "FTAB"),
("3d-mvc", "MVC"),
("4K", None),
("Director's Cut", None),
("", None),
(None, None),
],
)
def test_normalize_3d_label(label, expected):
assert normalize_3d_label(label) == expected
class TestMediaFilename:
def test_no_label_is_the_bare_stem(self):
assert media_filename("Matrix (1999)", "", ".mkv", grouped=False) == \
"Matrix (1999).mkv"
assert (
media_filename("Matrix (1999)", "", ".mkv", grouped=False)
== "Matrix (1999).mkv"
)
def test_3d_label_uses_jellyfins_documented_form(self):
assert media_filename("Avatar (2009)", "3D HSBS", ".mkv", grouped=False) == \
"Avatar (2009).3D.HSBS.mkv"
assert (
media_filename("Avatar (2009)", "3D HSBS", ".mkv", grouped=False)
== "Avatar (2009).3D.HSBS.mkv"
)
# same spelling grouped — "." is a valid separator after the folder name
assert media_filename("Avatar (2009)", "hsbs", ".mkv", grouped=True) == \
"Avatar (2009).3D.HSBS.mkv"
assert (
media_filename("Avatar (2009)", "hsbs", ".mkv", grouped=True)
== "Avatar (2009).3D.HSBS.mkv"
)
def test_plain_label_uses_dash_form(self):
assert media_filename("Avatar (2009)", "4K", ".mkv", grouped=True) == \
"Avatar (2009) - 4K.mkv"
assert (
media_filename("Avatar (2009)", "4K", ".mkv", grouped=True)
== "Avatar (2009) - 4K.mkv"
)
def test_grouped_empty_label_gets_a_default(self):
assert media_filename("Avatar (2009)", "", ".mkv", grouped=True) == \
f"Avatar (2009) - {DEFAULT_VERSION_LABEL}.mkv"
assert (
media_filename("Avatar (2009)", "", ".mkv", grouped=True)
== f"Avatar (2009) - {DEFAULT_VERSION_LABEL}.mkv"
)
class TestIdentityKey:
@@ -59,8 +80,13 @@ class TestIdentityKey:
def _movie(**kwargs) -> Movie:
base = dict(key="tmdb-19995", title="Avatar", year="2009", tmdb_id=19995,
library="Filmy")
base = {
"key": "tmdb-19995",
"title": "Avatar",
"year": "2009",
"tmdb_id": 19995,
"library": "Filmy",
}
base.update(kwargs)
return Movie(**base)
@@ -77,50 +103,66 @@ class TestMovieShape:
assert m.is_grouped is False
def test_two_videos_are_grouped(self):
m = _movie(media=[MediaFile(Path("/a.mkv"), "3D HSBS"),
MediaFile(Path("/b.mkv"), "Výchozí")])
m = _movie(
media=[
MediaFile(Path("/a.mkv"), "3D HSBS"),
MediaFile(Path("/b.mkv"), "Výchozí"),
]
)
assert m.is_grouped is True
def test_primary_prefers_the_plain_version(self):
m = _movie(media=[MediaFile(Path("/a.mkv"), "3D HSBS"),
MediaFile(Path("/b.mkv"), "")])
m = _movie(
media=[MediaFile(Path("/a.mkv"), "3D HSBS"), MediaFile(Path("/b.mkv"), "")]
)
assert m.primary.label == ""
class TestDesiredLayout:
def test_one_video_stays_flat_in_the_library(self, tmp_path):
m = _movie(media=[MediaFile(tmp_path / "kdekoli.mkv", "")])
(media, target), = m.desired_layout(tmp_path)
((_media, target),) = m.desired_layout(tmp_path)
assert target == tmp_path / "Filmy" / "Avatar (2009) [tmdbid-19995].mkv"
def test_one_3d_video_keeps_the_3d_tag_flat(self, tmp_path):
m = _movie(media=[MediaFile(tmp_path / "x.mkv", "3D HSBS")])
(_m, target), = m.desired_layout(tmp_path)
((_m, target),) = m.desired_layout(tmp_path)
assert target.name == "Avatar (2009) [tmdbid-19995].3D.HSBS.mkv"
assert target.parent == tmp_path / "Filmy"
def test_two_videos_move_into_the_movie_folder(self, tmp_path):
m = _movie(media=[MediaFile(tmp_path / "a.mkv", ""),
MediaFile(tmp_path / "b.mkv", "3D HSBS")])
m = _movie(
media=[
MediaFile(tmp_path / "a.mkv", ""),
MediaFile(tmp_path / "b.mkv", "3D HSBS"),
]
)
targets = {mf.label: path for mf, path in m.desired_layout(tmp_path)}
folder = tmp_path / "Filmy" / "Avatar (2009) [tmdbid-19995]"
assert targets[""] == folder / \
f"Avatar (2009) [tmdbid-19995] - {DEFAULT_VERSION_LABEL}.mkv"
assert (
targets[""]
== folder / f"Avatar (2009) [tmdbid-19995] - {DEFAULT_VERSION_LABEL}.mkv"
)
assert targets["3D HSBS"] == folder / "Avatar (2009) [tmdbid-19995].3D.HSBS.mkv"
def test_layout_follows_a_retitle(self, tmp_path):
"""Renaming the movie is just a different desired layout — the thing
that used to be impossible for a grouped movie."""
m = _movie(title="Avatar: Nová verze",
media=[MediaFile(tmp_path / "a.mkv", "A"),
MediaFile(tmp_path / "b.mkv", "B")])
m = _movie(
title="Avatar: Nová verze",
media=[
MediaFile(tmp_path / "a.mkv", "A"),
MediaFile(tmp_path / "b.mkv", "B"),
],
)
folders = {path.parent for _mf, path in m.desired_layout(tmp_path)}
assert folders == {
tmp_path / "Filmy" / "Avatar: Nová verze (2009) [tmdbid-19995]"}
tmp_path / "Filmy" / "Avatar: Nová verze (2009) [tmdbid-19995]"
}
def test_layout_follows_a_library_move(self, tmp_path):
m = _movie(library="Kids", media=[MediaFile(tmp_path / "a.mkv", "")])
(_m, target), = m.desired_layout(tmp_path)
((_m, target),) = m.desired_layout(tmp_path)
assert target.parent == tmp_path / "Kids"
@@ -128,12 +170,16 @@ class TestRecordRoundTrip:
def test_to_and_from_record(self, tmp_path):
m = _movie(
media=[MediaFile(tmp_path / "Filmy" / "a.mkv", "3D HSBS")],
csfd_url="https://www.csfd.cz/film/1/", date="2026-01-01",
attributes={"collection_sort": "01"}, meta={"year": "2009"})
csfd_url="https://www.csfd.cz/film/1/",
date="2026-01-01",
attributes={"collection_sort": "01"},
meta={"year": "2009"},
)
record = m.to_record(tmp_path)
assert record["media"] == [
{"role": "video", "label": "3D HSBS", "file": "Filmy/a.mkv"}]
{"role": "video", "label": "3D HSBS", "file": "Filmy/a.mkv"}
]
back = Movie.from_record("tmdb-19995", record, tmp_path)
assert back.title == "Avatar"
@@ -148,8 +194,31 @@ class TestRecordRoundTrip:
def test_from_record_builds_tags_via_tagmanager(self, tmp_path):
from src.core.tag_manager import TagManager
record = {"title": "Avatar", "media": [], "tags": ["Žánr/Sci-Fi"]}
back = Movie.from_record("tmdb-19995", record, tmp_path, TagManager())
assert {t.full_path for t in back.tags} == {"Žánr/Sci-Fi"}
@pytest.mark.parametrize(
"label,expected",
[
("part1", 1),
("Part 2", 2),
("pt3", 3),
("CD1", 1),
("disc-2", 2),
("dvd_4", 4),
("disk12", 12),
("4K", None),
("3D HSBS", None),
("", None),
("partition", None),
],
)
def test_normalize_part_label(label, expected):
from src.core.movie import normalize_part_label
assert normalize_part_label(label) == expected