fix: strip all trailing year suffixes to prevent duplication

- series.py: use regex to remove all trailing (YYYY) before appending year
- nfo_service.py: _extract_year_from_name strips all trailing year suffixes
- nfo_repair_service.py: add _read_tmdb_id() helper to extract TMDB ID from NFO
This commit is contained in:
2026-05-20 19:38:37 +02:00
parent 7930e49701
commit 51be777e7d
3 changed files with 38 additions and 5 deletions

View File

@@ -271,10 +271,11 @@ class Serie:
'Dororo (2025)' 'Dororo (2025)'
""" """
if self._year: if self._year:
import re
year_suffix = f" ({self._year})" year_suffix = f" ({self._year})"
if self._name.endswith(year_suffix): # Strip ALL trailing year suffixes before appending to prevent duplication
return self._name clean_name = re.sub(r'(\s*\(\d{4}\))+\s*$', '', self._name).strip()
return f"{self._name}{year_suffix}" return f"{clean_name}{year_suffix}"
return self._name return self._name
@property @property

View File

@@ -120,6 +120,37 @@ def nfo_needs_repair(nfo_path: Path) -> bool:
return bool(find_missing_tags(nfo_path)) return bool(find_missing_tags(nfo_path))
def _read_tmdb_id(nfo_path: Path) -> int | None:
"""Return the TMDB ID stored in an existing NFO, or ``None``.
Checks both ``<tmdbid>`` and ``<uniqueid type="tmdb">`` elements.
Args:
nfo_path: Absolute path to the ``tvshow.nfo`` file.
Returns:
Integer TMDB ID, or ``None`` if not found or not parseable.
"""
if not nfo_path.exists():
return None
try:
root = etree.parse(str(nfo_path)).getroot()
for uniqueid in root.findall(".//uniqueid"):
if uniqueid.get("type") == "tmdb" and uniqueid.text:
return int(uniqueid.text)
tmdbid_elem = root.find(".//tmdbid")
if tmdbid_elem is not None and tmdbid_elem.text:
return int(tmdbid_elem.text)
except (etree.XMLSyntaxError, ValueError):
pass
except Exception: # pylint: disable=broad-except
pass
return None
class NfoRepairService: class NfoRepairService:
"""Service that detects and repairs incomplete tvshow.nfo files. """Service that detects and repairs incomplete tvshow.nfo files.

View File

@@ -83,11 +83,12 @@ class NFOService:
>>> _extract_year_from_name("Attack on Titan") >>> _extract_year_from_name("Attack on Titan")
("Attack on Titan", None) ("Attack on Titan", None)
""" """
# Match year in parentheses at the end: (YYYY) # Match the last year in parentheses at the end: (YYYY)
match = re.search(r'\((\d{4})\)\s*$', serie_name) match = re.search(r'\((\d{4})\)\s*$', serie_name)
if match: if match:
year = int(match.group(1)) year = int(match.group(1))
clean_name = serie_name[:match.start()].strip() # Strip ALL trailing year suffixes to get a fully clean name
clean_name = re.sub(r'(\s*\(\d{4}\))+\s*$', '', serie_name).strip()
return clean_name, year return clean_name, year
return serie_name, None return serie_name, None