Fix NFO service year extraction from series names

This commit is contained in:
2026-01-19 20:42:04 +01:00
parent 6d40ddbfe5
commit 01f828c799
3 changed files with 287 additions and 90 deletions

View File

@@ -9,8 +9,9 @@ Example:
"""
import logging
import re
from pathlib import Path
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple
from lxml import etree
@@ -58,6 +59,44 @@ class NFOService:
self.image_size = image_size
self.auto_create = auto_create
def has_nfo(self, serie_folder: str) -> bool:
"""Check if tvshow.nfo exists for a series.
Args:
serie_folder: Series folder name
Returns:
True if NFO file exists
"""
nfo_path = self.anime_directory / serie_folder / "tvshow.nfo"
return nfo_path.exists()
@staticmethod
def _extract_year_from_name(serie_name: str) -> Tuple[str, Optional[int]]:
"""Extract year from series name if present in format 'Name (YYYY)'.
Args:
serie_name: Series name, possibly with year in parentheses
Returns:
Tuple of (clean_name, year)
- clean_name: Series name without year
- year: Extracted year or None
Examples:
>>> _extract_year_from_name("Attack on Titan (2013)")
("Attack on Titan", 2013)
>>> _extract_year_from_name("Attack on Titan")
("Attack on Titan", None)
"""
# Match year in parentheses at the end: (YYYY)
match = re.search(r'\((\d{4})\)\s*$', serie_name)
if match:
year = int(match.group(1))
clean_name = serie_name[:match.start()].strip()
return clean_name, year
return serie_name, None
async def check_nfo_exists(self, serie_folder: str) -> bool:
"""Check if tvshow.nfo exists for a series.
@@ -82,9 +121,10 @@ class NFOService:
"""Create tvshow.nfo by scraping TMDB.
Args:
serie_name: Name of the series to search
serie_name: Name of the series to search (may include year in parentheses)
serie_folder: Series folder name
year: Release year (helps narrow search)
year: Release year (helps narrow search). If None and name contains year,
year will be auto-extracted
download_poster: Whether to download poster.jpg
download_logo: Whether to download logo.png
download_fanart: Whether to download fanart.jpg
@@ -96,7 +136,16 @@ class NFOService:
TMDBAPIError: If TMDB API fails
FileNotFoundError: If series folder doesn't exist
"""
logger.info(f"Creating NFO for {serie_name} (year: {year})")
# Extract year from name if not provided
clean_name, extracted_year = self._extract_year_from_name(serie_name)
if year is None and extracted_year is not None:
year = extracted_year
logger.info(f"Extracted year {year} from series name")
# Use clean name for search
search_name = clean_name
logger.info(f"Creating NFO for {search_name} (year: {year})")
folder_path = self.anime_directory / serie_folder
if not folder_path.exists():
@@ -104,15 +153,15 @@ class NFOService:
folder_path.mkdir(parents=True, exist_ok=True)
async with self.tmdb_client:
# Search for TV show
logger.debug(f"Searching TMDB for: {serie_name}")
search_results = await self.tmdb_client.search_tv_show(serie_name)
# Search for TV show with clean name (without year)
logger.debug(f"Searching TMDB for: {search_name}")
search_results = await self.tmdb_client.search_tv_show(search_name)
if not search_results.get("results"):
raise TMDBAPIError(f"No results found for: {serie_name}")
raise TMDBAPIError(f"No results found for: {search_name}")
# Find best match (consider year if provided)
tv_show = self._find_best_match(search_results["results"], serie_name, year)
tv_show = self._find_best_match(search_results["results"], search_name, year)
tv_id = tv_show["id"]
logger.info(f"Found match: {tv_show['name']} (ID: {tv_id})")