feat(dot_alfred): load_by_tmdb_id on release repos
Series repo returns (release, folder) so the upcoming sync orchestrator can feed the library index's upsert(..., path=...). Movie repo returns the release alone (folder is on release.folder by the one-folder-one-file convention) — kept as a semantic alias of find_by_tmdb_id for symmetry with the series side.
This commit is contained in:
@@ -117,6 +117,21 @@ class DotAlfredSeriesReleaseRepository:
|
|||||||
return release
|
return release
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def load_by_tmdb_id(
|
||||||
|
self, tmdb_id: TmdbId
|
||||||
|
) -> tuple[SeriesRelease, str] | None:
|
||||||
|
"""Return ``(release, show_folder_name)`` for ``tmdb_id``, or ``None``.
|
||||||
|
|
||||||
|
Same lookup as :meth:`find_by_tmdb_id` but also returns the
|
||||||
|
folder name the release lives in — needed by the upcoming
|
||||||
|
sync orchestrator to feed the library index's ``upsert(...,
|
||||||
|
path=...)``.
|
||||||
|
"""
|
||||||
|
for folder, release in self._iter_library():
|
||||||
|
if release.tmdb_id == tmdb_id:
|
||||||
|
return release, folder
|
||||||
|
return None
|
||||||
|
|
||||||
def find_all(self) -> list[SeriesRelease]:
|
def find_all(self) -> list[SeriesRelease]:
|
||||||
"""Return every readable release under ``library_root/``.
|
"""Return every readable release under ``library_root/``.
|
||||||
|
|
||||||
@@ -198,6 +213,18 @@ class DotAlfredMovieReleaseRepository:
|
|||||||
return release
|
return release
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def load_by_tmdb_id(self, tmdb_id: TmdbId) -> MovieRelease | None:
|
||||||
|
"""Return the :class:`MovieRelease` for ``tmdb_id``, or ``None``.
|
||||||
|
|
||||||
|
Movies carry their folder on ``release.folder`` (one-folder-
|
||||||
|
one-file convention), so no separate folder name is returned —
|
||||||
|
this is just a semantic alias of :meth:`find_by_tmdb_id`
|
||||||
|
provided for symmetry with
|
||||||
|
:meth:`DotAlfredSeriesReleaseRepository.load_by_tmdb_id`, the
|
||||||
|
sync orchestrators rely on the same name on both sides.
|
||||||
|
"""
|
||||||
|
return self.find_by_tmdb_id(tmdb_id)
|
||||||
|
|
||||||
def find_all(self) -> list[MovieRelease]:
|
def find_all(self) -> list[MovieRelease]:
|
||||||
return [release for _folder, release in self._iter_library()]
|
return [release for _folder, release in self._iter_library()]
|
||||||
|
|
||||||
|
|||||||
@@ -90,6 +90,30 @@ class TestSeriesReleaseRepositoryReads:
|
|||||||
assert len(results) == 1
|
assert len(results) == 1
|
||||||
|
|
||||||
|
|
||||||
|
class TestSeriesReleaseRepositoryLoadByTmdbId:
|
||||||
|
def test_returns_release_and_folder_tuple(
|
||||||
|
self, tv_library, foundation_release
|
||||||
|
):
|
||||||
|
repo = DotAlfredSeriesReleaseRepository(tv_library)
|
||||||
|
repo.save(foundation_release, show_folder="Foundation")
|
||||||
|
result = repo.load_by_tmdb_id(TmdbId(84958))
|
||||||
|
assert result is not None
|
||||||
|
release, folder = result
|
||||||
|
assert release == foundation_release
|
||||||
|
assert folder == "Foundation"
|
||||||
|
|
||||||
|
def test_returns_none_when_tmdb_id_absent(
|
||||||
|
self, tv_library, foundation_release
|
||||||
|
):
|
||||||
|
repo = DotAlfredSeriesReleaseRepository(tv_library)
|
||||||
|
repo.save(foundation_release, show_folder="Foundation")
|
||||||
|
assert repo.load_by_tmdb_id(TmdbId(999999)) is None
|
||||||
|
|
||||||
|
def test_returns_none_on_empty_library(self, tv_library):
|
||||||
|
repo = DotAlfredSeriesReleaseRepository(tv_library)
|
||||||
|
assert repo.load_by_tmdb_id(TmdbId(84958)) is None
|
||||||
|
|
||||||
|
|
||||||
class TestSeriesReleaseRepositoryDelete:
|
class TestSeriesReleaseRepositoryDelete:
|
||||||
def test_delete_removes_sidecar(self, tv_library, foundation_release):
|
def test_delete_removes_sidecar(self, tv_library, foundation_release):
|
||||||
repo = DotAlfredSeriesReleaseRepository(tv_library)
|
repo = DotAlfredSeriesReleaseRepository(tv_library)
|
||||||
@@ -123,6 +147,20 @@ class TestMovieReleaseRepository:
|
|||||||
restored = repo.find_by_tmdb_id(TmdbId(27205))
|
restored = repo.find_by_tmdb_id(TmdbId(27205))
|
||||||
assert restored == inception_release
|
assert restored == inception_release
|
||||||
|
|
||||||
|
def test_load_by_tmdb_id_returns_release(
|
||||||
|
self, movie_library, inception_release
|
||||||
|
):
|
||||||
|
repo = DotAlfredMovieReleaseRepository(movie_library)
|
||||||
|
repo.save(inception_release)
|
||||||
|
assert repo.load_by_tmdb_id(TmdbId(27205)) == inception_release
|
||||||
|
|
||||||
|
def test_load_by_tmdb_id_returns_none_when_absent(
|
||||||
|
self, movie_library, inception_release
|
||||||
|
):
|
||||||
|
repo = DotAlfredMovieReleaseRepository(movie_library)
|
||||||
|
repo.save(inception_release)
|
||||||
|
assert repo.load_by_tmdb_id(TmdbId(999999)) is None
|
||||||
|
|
||||||
def test_anchor_mismatch_logs_warning(
|
def test_anchor_mismatch_logs_warning(
|
||||||
self, movie_library, inception_release, caplog
|
self, movie_library, inception_release, caplog
|
||||||
):
|
):
|
||||||
|
|||||||
Reference in New Issue
Block a user