feat: Implement NFOService.update_tvshow_nfo()
- Parse existing NFO to extract TMDB ID from uniqueid or tmdbid element - Fetch fresh metadata from TMDB API - Regenerate NFO with updated data - Optionally re-download media files - Add comprehensive error handling (missing NFO, no TMDB ID, invalid XML) - Add unit tests for XML parsing logic (4 tests, all passing) - Add integration test script (requires TMDB API key)
This commit is contained in:
@@ -12,6 +12,8 @@ import logging
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from src.core.entities.nfo_models import (
|
||||
ActorInfo,
|
||||
ImageInfo,
|
||||
@@ -158,21 +160,76 @@ class NFOService:
|
||||
|
||||
Raises:
|
||||
FileNotFoundError: If NFO file doesn't exist
|
||||
TMDBAPIError: If TMDB API fails
|
||||
TMDBAPIError: If TMDB API fails or no TMDB ID found in NFO
|
||||
"""
|
||||
nfo_path = self.anime_directory / serie_folder / "tvshow.nfo"
|
||||
folder_path = self.anime_directory / serie_folder
|
||||
nfo_path = folder_path / "tvshow.nfo"
|
||||
|
||||
if not nfo_path.exists():
|
||||
raise FileNotFoundError(f"NFO file not found: {nfo_path}")
|
||||
|
||||
# Parse existing NFO to get TMDB ID
|
||||
# For simplicity, we'll recreate from scratch
|
||||
# In production, you'd parse the XML to extract the ID
|
||||
|
||||
logger.info(f"Updating NFO for {serie_folder}")
|
||||
# Implementation would extract serie name and call create_tvshow_nfo
|
||||
# This is a simplified version
|
||||
raise NotImplementedError("Update NFO not yet implemented")
|
||||
|
||||
# Parse existing NFO to extract TMDB ID
|
||||
try:
|
||||
tree = etree.parse(str(nfo_path))
|
||||
root = tree.getroot()
|
||||
|
||||
# Try to find TMDB ID from uniqueid elements
|
||||
tmdb_id = None
|
||||
for uniqueid in root.findall(".//uniqueid"):
|
||||
if uniqueid.get("type") == "tmdb":
|
||||
tmdb_id = int(uniqueid.text)
|
||||
break
|
||||
|
||||
# Fallback: check for tmdbid element
|
||||
if tmdb_id is None:
|
||||
tmdbid_elem = root.find(".//tmdbid")
|
||||
if tmdbid_elem is not None and tmdbid_elem.text:
|
||||
tmdb_id = int(tmdbid_elem.text)
|
||||
|
||||
if tmdb_id is None:
|
||||
raise TMDBAPIError(
|
||||
f"No TMDB ID found in existing NFO. "
|
||||
f"Delete the NFO and create a new one instead."
|
||||
)
|
||||
|
||||
logger.debug(f"Found TMDB ID: {tmdb_id}")
|
||||
|
||||
except etree.XMLSyntaxError as e:
|
||||
raise TMDBAPIError(f"Invalid XML in NFO file: {e}")
|
||||
except ValueError as e:
|
||||
raise TMDBAPIError(f"Invalid TMDB ID format in NFO: {e}")
|
||||
|
||||
# Fetch fresh data from TMDB
|
||||
async with self.tmdb_client:
|
||||
logger.debug(f"Fetching fresh data for TMDB ID: {tmdb_id}")
|
||||
details = await self.tmdb_client.get_tv_show_details(
|
||||
tmdb_id,
|
||||
append_to_response="credits,external_ids,images"
|
||||
)
|
||||
|
||||
# Convert TMDB data to TVShowNFO model
|
||||
nfo_model = self._tmdb_to_nfo_model(details)
|
||||
|
||||
# Generate XML
|
||||
nfo_xml = generate_tvshow_nfo(nfo_model)
|
||||
|
||||
# Save updated NFO file
|
||||
nfo_path.write_text(nfo_xml, encoding="utf-8")
|
||||
logger.info(f"Updated NFO: {nfo_path}")
|
||||
|
||||
# Re-download media files if requested
|
||||
if download_media:
|
||||
await self._download_media_files(
|
||||
details,
|
||||
folder_path,
|
||||
download_poster=True,
|
||||
download_logo=True,
|
||||
download_fanart=True
|
||||
)
|
||||
|
||||
return nfo_path
|
||||
|
||||
def _find_best_match(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user