feat(SerieScanner): DB lookup primary, deprecate key file fallback

DB now source of truth for folder -> Serie resolution.

Changes:
- AnimeSeriesService.get_by_folder(): new async lookup by folder name
- SerieScanner.__read_data_from_file(): query DB first, then provider callback, then legacy key file (temporary, removed v3.0.0)
- Serie: reconstruct from DB record with episode dict
- Key file: warn on use, scheduled removal v3.0.0

Add unit tests for DB hit/miss/callback/fallback edge cases

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-26 17:56:37 +02:00
parent cbd53ef2a0
commit 841368bf85
3 changed files with 219 additions and 32 deletions

View File

@@ -169,6 +169,26 @@ class AnimeSeriesService:
)
return result.scalar_one_or_none()
@staticmethod
async def get_by_folder(db: AsyncSession, folder: str) -> Optional[AnimeSeries]:
"""Look up an anime series by its filesystem folder name (async).
Intended as primary lookup for ``SerieScanner`` when scanning
directories, replacing the legacy file-based lookups (key/data files).
Args:
db: Async database session.
folder: Filesystem folder name to match (e.g.
``"Rooster Fighter (2026)"``).
Returns:
``AnimeSeries`` instance or ``None`` if not found.
"""
result = await db.execute(
select(AnimeSeries).where(AnimeSeries.folder == folder)
)
return result.scalar_one_or_none()
@staticmethod
async def get_all(
db: AsyncSession,