Remove redundant episode loading step
- Merged _load_episodes() functionality into _scan_missing_episodes() - _scan_missing_episodes() already queries provider and compares with filesystem - Eliminates duplicate filesystem scanning during series add - Simplifies background loading flow: NFO → Episode Discovery
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
from functools import lru_cache
|
||||
from typing import Optional
|
||||
|
||||
@@ -733,6 +734,98 @@ class AnimeService:
|
||||
# Load into SeriesApp
|
||||
self._app.load_series_from_list(series_list)
|
||||
|
||||
async def sync_episodes_to_db(self, series_key: str) -> int:
|
||||
"""
|
||||
Sync episodes from in-memory SeriesApp to database for a specific series.
|
||||
|
||||
This method reads the episodeDict from the in-memory series (populated
|
||||
by scanner) and syncs it to the database. Called after scanning for
|
||||
missing episodes.
|
||||
|
||||
Args:
|
||||
series_key: The series key to sync episodes for
|
||||
|
||||
Returns:
|
||||
Number of episodes synced to database
|
||||
"""
|
||||
from src.server.database.connection import get_db_session
|
||||
from src.server.database.service import AnimeSeriesService, EpisodeService
|
||||
|
||||
# Get the serie from in-memory cache
|
||||
if not hasattr(self._app, 'list') or not hasattr(self._app.list, 'keyDict'):
|
||||
logger.warning(f"Series list not available for episode sync: {series_key}")
|
||||
return 0
|
||||
|
||||
serie = self._app.list.keyDict.get(series_key)
|
||||
if not serie:
|
||||
logger.warning(f"Series not found in memory for episode sync: {series_key}")
|
||||
return 0
|
||||
|
||||
episodes_added = 0
|
||||
|
||||
async with get_db_session() as db:
|
||||
# Get series from database
|
||||
series_db = await AnimeSeriesService.get_by_key(db, series_key)
|
||||
if not series_db:
|
||||
logger.warning(f"Series not found in database: {series_key}")
|
||||
return 0
|
||||
|
||||
# Get existing episodes from database
|
||||
existing_episodes = await EpisodeService.get_by_series(db, series_db.id)
|
||||
|
||||
# Build dict of existing episodes: {season: {ep_num: episode_id}}
|
||||
existing_dict: dict[int, dict[int, int]] = {}
|
||||
for ep in existing_episodes:
|
||||
if ep.season not in existing_dict:
|
||||
existing_dict[ep.season] = {}
|
||||
existing_dict[ep.season][ep.episode_number] = ep.id
|
||||
|
||||
# Get new missing episodes from in-memory serie
|
||||
new_dict = serie.episodeDict or {}
|
||||
|
||||
# Add new missing episodes that are not in the database
|
||||
for season, episode_numbers in new_dict.items():
|
||||
existing_season_eps = existing_dict.get(season, {})
|
||||
for ep_num in episode_numbers:
|
||||
if ep_num not in existing_season_eps:
|
||||
await EpisodeService.create(
|
||||
db=db,
|
||||
series_id=series_db.id,
|
||||
season=season,
|
||||
episode_number=ep_num,
|
||||
)
|
||||
episodes_added += 1
|
||||
logger.debug(
|
||||
f"Added missing episode to database: {series_key} S{season:02d}E{ep_num:02d}"
|
||||
)
|
||||
|
||||
if episodes_added > 0:
|
||||
logger.info(
|
||||
f"Synced {episodes_added} missing episodes to database for {series_key}"
|
||||
)
|
||||
|
||||
# Broadcast update to frontend to refresh series list
|
||||
try:
|
||||
await self._broadcast_series_updated(series_key)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to broadcast series update: {e}")
|
||||
|
||||
return episodes_added
|
||||
|
||||
async def _broadcast_series_updated(self, series_key: str) -> None:
|
||||
"""Broadcast series update event to WebSocket clients."""
|
||||
if not self._websocket_service:
|
||||
return
|
||||
|
||||
payload = {
|
||||
"type": "series_updated",
|
||||
"key": series_key,
|
||||
"message": "Episodes updated",
|
||||
"timestamp": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
|
||||
await self._websocket_service.broadcast(payload)
|
||||
|
||||
async def add_series_to_db(
|
||||
self,
|
||||
serie,
|
||||
|
||||
Reference in New Issue
Block a user