Add edit dialogs, library organizer, and TMDb pool migration

This commit is contained in:
2026-09-08 07:37:40 +02:00
parent 39712d7283
commit 79c9e34a5d
10 changed files with 1371 additions and 110 deletions
+137 -1
View File
@@ -427,6 +427,92 @@ class TestPoolManagement:
assert movie.file_path.name == "Matrix (1999) [tmdbid-603].mkv"
assert movie.title == "Matrix" # clean title, no year/id
def test_libraries_default_and_derivation(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
assert file_manager.libraries == [
{"name": "Filmy", "kind": "movie"},
{"name": "Seriály", "kind": "series"},
]
assert file_manager.movie_libraries == ["Filmy"]
assert file_manager.copyasis_folders == ["Seriály"]
def test_set_libraries_with_all_kinds(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_libraries([
{"name": "Hlavní", "kind": "mixed"},
{"name": "Dokumenty", "kind": "mixed"},
{"name": "Anime", "kind": "series"},
{"name": "Chajda", "kind": "homevideo"},
])
assert file_manager.copyasis_folders == ["Anime"]
assert file_manager.movie_libraries == ["Filmy"] # none of kind movie → fallback
assert file_manager.libraries_of_kind("mixed") == ["Hlavní", "Dokumenty"]
assert file_manager.libraries_of_kind("homevideo") == ["Chajda"]
def test_set_pool_dir_creates_all_library_folders(self, file_manager, tmp_path):
pool = tmp_path / "pool"
file_manager.set_pool_dir(pool)
file_manager.set_libraries([
{"name": "Hlavní", "kind": "mixed"},
{"name": "Chajda", "kind": "homevideo"},
])
file_manager.set_pool_dir(pool) # re-run creates the newly defined folders
assert (pool / "Hlavní").is_dir()
assert (pool / "Chajda").is_dir()
def test_mixed_library_loads_movies_not_episodes(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_libraries([{"name": "Hlavní", "kind": "mixed"}])
hlavni = tmp_path / "pool" / "Hlavní"
hlavni.mkdir(parents=True, exist_ok=True)
(hlavni / "Matrix (1999) [tmdbid-603].mkv").write_bytes(b"x") # movie (top level)
ep = hlavni / "Breaking Bad (2008) [tmdbid-1396]" / "Season 01"
ep.mkdir(parents=True)
(ep / "S01E01 - pilot.mkv").write_bytes(b"y") # series episode (subfolder)
file_manager.load_pool_movies()
names = [f.filename for f in file_manager.filelist]
assert names == ["Matrix (1999) [tmdbid-603].mkv"] # episode not loaded as movie
assert file_manager.library_of(file_manager.filelist[0]) == "Hlavní"
def test_libraries_accepting_movies(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_libraries([
{"name": "Filmy", "kind": "movie"},
{"name": "Hlavní", "kind": "mixed"},
{"name": "Anime", "kind": "series"},
])
assert file_manager.libraries_accepting_movies == ["Filmy", "Hlavní"]
def test_orphan_folder_cleanup(self, file_manager, tmp_path):
pool = tmp_path / "pool"
file_manager.set_pool_dir(pool)
file_manager.set_libraries([{"name": "Filmy", "kind": "movie"}])
(pool / "OldKids").mkdir() # empty orphan
(pool / "OldStuff").mkdir()
(pool / "OldStuff" / "film.mkv").write_bytes(b"x") # non-empty orphan
orphans = dict(file_manager.orphan_pool_folders())
assert orphans.get("OldKids") is True
assert orphans.get("OldStuff") is False
assert "Filmy" not in orphans # a configured library is not an orphan
assert file_manager.remove_empty_pool_folder("OldKids") is True
assert not (pool / "OldKids").exists()
assert file_manager.remove_empty_pool_folder("OldStuff") is False # non-empty
assert file_manager.remove_empty_pool_folder("Filmy") is False # a library
def test_move_movie_into_mixed_library(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_libraries([
{"name": "Filmy", "kind": "movie"},
{"name": "Hlavní", "kind": "mixed"},
])
(tmp_path / "a.mkv").write_bytes(b"x")
movie = file_manager.import_movie(tmp_path / "a.mkv", "Matrix", year=1999)
file_manager.move_to_library(movie, "Hlavní")
assert file_manager.library_of(movie) == "Hlavní"
def test_import_into_named_library(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_movie_libraries(["Filmy", "Kids"])
@@ -490,6 +576,52 @@ class TestPoolManagement:
assert len(reloaded.filelist) == 1
assert reloaded.filelist[0].file_path.suffix == ".mkv"
def test_apply_movie_edits_all_at_once(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
file_manager.set_movie_libraries(["Filmy", "Kids"])
(tmp_path / "a.mkv").write_bytes(b"x")
movie = file_manager.import_movie(tmp_path / "a.mkv", "Puvodni", year=2000)
file_manager.apply_movie_edits(
movie, title="Auta", year=2006, tmdb_id=920, library="Kids",
date="2026-01-02", attributes={"collection_sort": "01"},
tags=["Žánr/Animovaný", "Sbírka/Oblíbené"])
assert movie.file_path == tmp_path / "pool" / "Kids" / "Auta (2006) [tmdbid-920].mkv"
assert movie.title == "Auta"
assert file_manager.library_of(movie) == "Kids"
assert movie.date == "2026-01-02"
assert movie.attributes == {"collection_sort": "01"}
assert {t.full_path for t in movie.tags} == {"Žánr/Animovaný", "Sbírka/Oblíbené"}
def test_import_and_edit_store_csfd_url(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
(tmp_path / "a.mkv").write_bytes(b"x")
movie = file_manager.import_movie(
tmp_path / "a.mkv", "Matrix", year=1999, tmdb_id=603,
csfd_url="https://www.csfd.cz/film/9499/")
assert movie.csfd_url == "https://www.csfd.cz/film/9499/"
# persists across reload
reloaded = FileManager(TagManager())
reloaded.set_pool_dir(tmp_path / "pool")
reloaded.load_pool_movies()
assert reloaded.filelist[0].csfd_url == "https://www.csfd.cz/film/9499/"
# editable via apply_movie_edits
file_manager.apply_movie_edits(movie, title="Matrix", year=1999,
csfd_url="https://www.csfd.cz/film/9499-matrix/")
assert movie.csfd_url == "https://www.csfd.cz/film/9499-matrix/"
def test_apply_movie_edits_rejects_name_clash(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
(tmp_path / "a.mkv").write_bytes(b"x")
(tmp_path / "b.mkv").write_bytes(b"y")
file_manager.import_movie(tmp_path / "a.mkv", "Solaris", year=1972)
other = file_manager.import_movie(tmp_path / "b.mkv", "Jiny", year=2002)
with pytest.raises(FileExistsError):
file_manager.apply_movie_edits(other, title="Solaris", year=1972)
def test_rename_to_canonical_preserves_tmdb_id(self, file_manager, tmp_path):
file_manager.set_pool_dir(tmp_path / "pool")
(tmp_path / "raw.mkv").write_bytes(b"x")
@@ -581,7 +713,11 @@ class TestPoolManagement:
file_manager.set_copyasis_folders(["Seriály", "Dokumenty"])
assert "copyasis_folders" not in file_manager.global_config
assert file_manager.index.get_setting("copyasis_folders") == ["Seriály", "Dokumenty"]
# series libraries now persist in the unified "libraries" setting (in the index)
stored = file_manager.index.get_setting("libraries")
assert stored is not None
assert [lib["name"] for lib in stored if lib["kind"] == "series"] == \
["Seriály", "Dokumenty"]
# a fresh manager over the same pool reads the stored settings back
reloaded = FileManager(TagManager())